In my SvelteKit project, I use adapter-static
. I want all pages to be prerendered, and after a page has been loaded by the web browser I want it to behave as an SPA.
The problem I'm having is that after I have built my project and am previewing it (npm run preview)
, then when I click on a link, the web browser fetches an entire new page, and does not only fetch the content for the new page (i.e. it does not function as an SPA). And I don't understand where I have gone wrong.
This is what I have:
svelte.config.js
// ...
const config = {
kit: {
adapter: adapterStatic(),
// ...
},
extensions: ['.svelte', '.md'],
// ...
}
src/routes/+layout.js
export const prerender = true
export const trailingSlash = 'always'
I don't set any of these options or any other options (like ssr
, csr
, etc.) in any other file as far as I know.
Have i missed something I need to add to turn it into an SPA after the first page has been loaded? Or can I have added something somewhere that disables the SPA functionality? If so, what?
I'm using the mdsvex preprocessor to have support for markdown files (all file content is written in .md
files), but I don't think that should affect anything related to this.
Turned out that some links in my real project worked as an SPA, while some didn't. The difference was that the ones that didn't work had the target attribute set to _self
, while the ones that did work didn't have this attribute at all.
I find it very strange that adding target="_self"
makes the element behave differently in SvelteKit, because _self
is the default value for that attribute in HTML. But apparently, this is intended behavior:
This is the intended behavior. Treating
target=_self
as a full page reload is common to a lot of SPA frameworks, and predated SvelteKit's other mechanisms for disabling client-side navigation.
https://github.com/sveltejs/kit/issues/9842#issuecomment-1534590823