Reputation: 185
I get error message this when build.
Cannot access
url.searchParams
on a page with prerendering enabled
How to load and use get parameter?
svelte.config.js
import adapter from '@sveltejs/adapter-static';
import preprocess from 'svelte-preprocess';
const config = {
preprocess: preprocess({
}),
kit: {
adapter: adapter({
pages: 'build',
assets: 'build',
fallback: null,
precompress: false
}),
prerender: {
default: true
},
trailingSlash: 'always'
}
};
export default config;
qna.svelte
...
import {page} from '$app/stores';
const id = $page.url.searchParams.get('id');
...
Upvotes: 8
Views: 4569
Reputation: 8258
You can also use beforeUpdate
:
<script>
let id = null;
beforeUpdate(() => {
id = url.searchParams.get('id');
});
</script>
<div>
<!-- Use `id ` -->
</div>
The advantage of beforeUpdate
compared to onMount
is that it will be re-evaluated when your page changes from /page-path?id=1
and /page-path?id=2
, unlike onMount
.
For more details on why you cannot use search parameters during prerendering, here is an comment from Rich:
When you prerender, you're writing files to the filesystem so that a simple webserver can serve them. Query parameters can't exist on the filesystem (both in the literal sense that
?
isn't an allowed character on all filesystems, and in the sense that the webserver will ignore them), so if you have a prerendered endpoint called/api/posts/get
then it doesn't matter how many times you call it with different parameters, it can only be saved as a file once. The files need to have different paths (/api/posts/[slug]
), or it won't work.
Upvotes: 1
Reputation: 66
You actually can use searchParams using adapter-static, but have to follow one rule. Any access to the searchParams has to be done in the Svelte onMount function.
Don't forget to handle the case where no parameter is provided. I think the prerendering won't provide any, so it would otherwise produce an error.
<!-- +page.svelte -->
<script>
import { page } from '$app/stores';
import { onMount } from 'svelte';
let id = '';
onMount(() => {
// save the id parameter if it's in the url or an empty string
id = $page.url.searchParams.get('id') || '';
});
</script>
{#if id}
<h2>The id is {id}.</h2>
{:else}
<h2>No id was provided.</h2>
{/if}
Upvotes: 3
Reputation: 149
Let me expand on some other answers: url.searchParams can be used with prerended Sveltekit pages, but not on the server side (since their isn't any for prerendered pages)
You can however use url.searchParams in onMount or in constructs like:
import {browser} from "$app/environment";
const searchParams = browser && $page.url.searchParams
if (searchParams && searchParams.get("myParam")) console.log("myParam is: ",myParam)
Note the imported browser variable which is true if the code is run on the client side in the browser.
For more details, see https://kit.svelte.dev/docs/page-options#prerender
Upvotes: 6
Reputation: 1003
Or you can use the hash-based approach and still have the statically built page check this out https://gist.github.com/woss/afbc7293cc2a6632db585e388ff64583
Upvotes: 0
Reputation: 16451
You cannot use the searchParams and have a prerendered site at the same time. There would be potentially infinite variants of your searchParams, so you would have to prerender an infinte number of pages.
If you want a dynamic site, do not prerender that page. You can mark individual pages for not prerendering
<script context="module">
export const prerender = false;
</script>
Note that now you will need a fallback
page and have to make sure to redirect these pages to the index.html otherwise you will get 404s
Upvotes: 6