Single-page apps
Add "spa": true to your config before your first bootstrap:
{ "region": "us-east-1", "siteName": "example", "spa": true,}A single-page app (SPA) is one index.html whose JavaScript router handles every path. With spa: true, a request for a path that has no file - /settings/profile, say - gets your index.html with a 200, so a deep link or a page refresh loads the app and its router takes over.
Set up your framework
Section titled “Set up your framework”Your build must write an index.html at the root of its output directory.
| Framework | What to set | Output directory |
|---|---|---|
| SvelteKit | adapter-static with fallback: 'index.html', and export const ssr = false in the root +layout.js |
build - set "paths": { "dist": "build" } |
| Vite (React, Vue, Solid, …) | nothing - vite build writes dist/index.html |
dist, the default |
The SvelteKit SPA example is a complete project you can copy.
App in a subdirectory of a larger repository? Set paths.app as well - see Monorepos.
How unknown paths are answered
Section titled “How unknown paths are answered”Your files are served from a private S3 bucket through CloudFront. A request for a directory URL resolves to its index document (/projects/ → /projects/index.html). A path with no file behind it makes S3 answer 403 or 404, and spa decides what CloudFront does next:
spa |
Visitor gets |
|---|---|
false (default) |
Your site’s /404.html, with status 404 |
true |
Your /index.html, with status 200 |
Real files still serve normally either way: /assets/app.js returns the file, not index.html.
What else to know
Section titled “What else to know”- PR previews ignore
spa. The shared preview distribution cannot route errors per pull request, so a deep link into a preview returns an error instead of the app. Start from the preview’s root URL and navigate from there. See PR previews. - The sitemap has one entry. Production sitemaps are built from the HTML files in your output, so an SPA’s sitemap lists only
/. See robots.txt and sitemap.xml. - SPA and SSR do not mix.
spaand anssrblock are mutually exclusive. To render on the server, see Server-rendered sites.
Related pages
Section titled “Related pages”- SvelteKit SPA example - a complete project to copy
- Monorepos - building an app that lives in a subdirectory
- Configuration reference:
spa- the key itself