svelte-adapter-azure-swa Svelte Themes

Svelte Adapter Azure Swa

SvelteKit adapter for Azure Static Web Apps.

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" />

:warning: 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 in a subfolder (e.g. ./my_app_location), then your api_location should include the path to that subfolder (e.g. my_app_location/build/server.) output_location should still be build/static.

Building with the correct version of Node

Oryx, Azure's build system, may attempt to build your application with an EOL version of Node that SvelteKit doesn't support. If you get an error like "Unsupported engine - Not compatible with your version of node/npm", you can force Oryx to use the correct version by setting an engines field in your app's package.json:

"engines": {
    "node": ">=18.13 <19"
}

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.

staticDir

The directory where the static assets will be placed. Most of the time, you shouldn't need to set this.

By default, the adapter will output the static JS, CSS and HTML files to the build/static folder. If you want to output it to a different directory instead you can set this option.

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

export default {
    kit: {
        ...
        adapter: azure({
            staticDir: 'custom/static'
        })
    }
};

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
                    }
                },
                platform: {
                    apiRuntime: 'node:20'
                }
            }
        })
    }
};

allowReservedSwaRoutes

In production, Azure SWA will route any requests to /api or /api/* to the SWA API backend. If you also define SvelteKit routes beginning with /api, those requests will work in dev, but return a 404 in production since the request will be routed to the SWA API. Because of this, the adapter will throw an error at build time if it detects any routes beginning with /api.

If you want to disable this check, you can set allowReservedSwaRoutes to true. However, this will not start routing /api requests to your SvelteKit app. SWA does not allow configuring the /api route.

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

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

esbuildOptions

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

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

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

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

This contains the client principal as parsed from the x-ms-client-principal request header. See the official SWA documentation or the types for further details.

This is currently only available when running in production on SWA. In addition, it is only available in certain circumstances in production - see this adapter issue for more details. Please report any issues you encounter.

context

All server requests to your SvelteKit app are handled by an Azure function. This property contains that Azure function's request context.

Monorepo support

If you're deploying your app from a monorepo, here's what you need to know.

The build currently fails if you use pnpm as a package manager. You can track this issue for updates. For now, you can work around the issue by using npm instead.

Also, since your SvelteKit app is in a subfolder of the monorepo, you will need to update your deployment workflow.

For instance, if you have the following folder structure:

apps/
    ├── sveltekit-app
    └── other-app

The app_location and api_location in your deployment configuration need to point to the apps/sveltekit-app subfolder. output_location should remain the same. Here's how that would look for an Azure SWA GitHub workflow:

steps:
     - uses: actions/checkout@v2
        with:
          submodules: true
      - name: Build And Deploy
        id: builddeploy
        uses: Azure/static-web-apps-deploy@v1
        with:
          azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ORANGE_GRASS_0778C6300 }}
          repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
          action: "upload"
          ###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
          # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
-         app_location: "./" # App source code path
-         api_location: "build/server" # Api source code path - optional
+         app_location: "./apps/sveltekit-app" # App source code path
+         api_location: "apps/sveltekit-app/build/server" # Api source code path - optional
          output_location: "build/static" # Built app content directory - optional
          ###### End of Repository/Build Configurations ######

Gotchas

Azure has its share of surprising or quirky behaviors. Here is an evolving list of things to look out for:

[!CAUTION] Azure silently strips the content-type header from requests that have no body.

SvelteKit form actions are valid with no parameters, which can lead to POST requests that have an empty body. Unfortunately, Azure deletes the content-type header when the request has an empty body, which breaks SvelteKit's logic for handling form actions. Until this is addressed by Azure, update to verson 0.20.1 which contains a workaround for this behavior.

Top categories

Loading Svelte Themes