/svelte-adapter-azure-swa

SvelteKit adapter for Azure Static Web Apps.

Primary LanguageJavaScriptMIT LicenseMIT

svelte-adapter-azure-swa

Adapter for Svelte apps that creates an Azure Static Web App, using an Azure function for dynamic server rendering. If your app is purely static, you may be able to use adapter-static instead.

See the demo folder for an example integration with the SvelteKit demo app. The demo is automatically deployed to Azure SWA on every commit to the main branch.

Usage

Run npm install -D svelte-adapter-azure-swa.

Then in your svelte.config.js:

import azure from 'svelte-adapter-azure-swa';

export default {
	kit: {
		...
		adapter: azure()
	}
};

And, if you use TypeScript, add this to the top of your src/app.d.ts:

/// <reference types="svelte-adapter-azure-swa" />

⚠️ IMPORTANT: you also need to configure your build so that your SvelteKit site deploys properly. Failing to do so will prevent the project from building and deploying. See the next section for instructions.

Azure configuration

When deploying to Azure, you will need to properly configure your build so that both the static files and API are deployed.

property value
app_location ./
api_location build/server
output_location build/static

If you use a custom API directory (see below), your api_location will be the same as the value you pass to apiDir.

If your app_location is not the repository root ./ but ./my_app_location, then you also need to change the api_location to my_app_location/build/server (but not the output_location).

Running locally with the Azure SWA CLI

You can debug using the Azure Static Web Apps CLI. Note that the CLI is currently in preview and you may encounter issues.

To run the CLI, install @azure/static-web-apps-cli and the Azure Functions Core Tools and add a swa-cli.config.json to your project (see sample below). Run npm run build to build your project and swa start to start the emulator. See the CLI docs for more information on usage.

Sample swa-cli.config.json

{
	"configurations": {
		"app": {
			"outputLocation": "./build/static",
			"apiLocation": "./build/server",
			"host": "127.0.0.1"
		}
	}
}

Options

apiDir

The directory where the sk_render Azure function for SSR will be placed. Most of the time, you shouldn't need to set this.

By default, the adapter will output the sk_render Azure function for SSR in the build/server folder. If you want to output it to a different directory instead (e.g. if you have additional Azure functions to deploy), you can set this option.

import azure from 'svelte-adapter-azure-swa';

export default {
	kit: {
		...
		adapter: azure({
			apiDir: 'custom/api'
		})
	}
};

If you set this option, you will also need to create a host.json and package.json in your API directory. The adapter normally generates these files by default, but skips them when a custom API directory is provided to prevent overwriting any existing files. You can see the default files the adapter generates in this directory.

For instance, by default the adapter outputs these files...

build/
└── server/
    ├── sk_render/
    │   ├── function.json
    │   └── index.js
    ├── host.json
    ├── local.settings.json
    └── package.json

... but only outputs these files when a custom API directory is provided:

custom/
└── api/
    └── sk_render/
        ├── function.json
        └── index.js

Also note that the adapter reserves the folder prefix sk_render and API route prefix __render for Azure functions generated by the adapter. So, if you use a custom API directory, you cannot have any other folder starting with sk_render or functions available at the __render route, since these will conflict with the adapter's Azure functions.

customStaticWebAppConfig

An object containing additional Azure SWA configuration options. This will be merged with the staticwebapp.config.json generated by the adapter.

Attempting to override the default catch-all route (route: '*') or the navigationFallback options will throw an error, since they are critical for server-side rendering.

Note: customizing this config (especially routes) has the potential to break how SvelteKit handles the request. Make sure to test any modifications thoroughly.

import azure from 'svelte-adapter-azure-swa';

export default {
	kit: {
		...
		adapter: azure({
			customStaticWebAppConfig: {
				routes: [
					{
						route: '/login',
						allowedRoles: ['admin']
					}
				],
				globalHeaders: {
					'X-Content-Type-Options': 'nosniff',
					'X-Frame-Options': 'DENY',
					'Content-Security-Policy': "default-src https: 'unsafe-eval' 'unsafe-inline'; object-src 'none'",
				},
				mimeTypes: {
					'.json': 'text/json'
				},
				responseOverrides: {
					'401': {
						'redirect': '/login',
						'statusCode': 302
					}
				}
			}
		})
	}
};

esbuildOptions

An object containing additional esbuild options. Currently only supports external. If you require additional options to be exposed, plese open an issue.

import azure from 'svelte-adapter-azure-swa';

export default {
	kit: {
		...
		adapter: azure({
			esbuildOptions: {
				external: ['fsevents']
			}
		})
	}
};

Platform-specific context

SWA provides some information to the backend functions that this adapter makes available as platform-specific context. This is available in hooks and server routes through the platform property on the RequestEvent.

To get typings for the platform property, reference this adapter in your src/app.d.ts as described in the usage section.

clientPrincipal

The client principal as passed in a header from SWA to the render function is available at platform.clientPrincipal in the same form it is provided by SWA. See the official SWA documentation or the types for further details.