Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic route parameter with SSR using static-adapter #2907

Closed
endigo9740 opened this issue Nov 24, 2021 · 4 comments · May be fixed by naiba4/kit#1
Closed

Dynamic route parameter with SSR using static-adapter #2907

endigo9740 opened this issue Nov 24, 2021 · 4 comments · May be fixed by naiba4/kit#1

Comments

@endigo9740
Copy link

endigo9740 commented Nov 24, 2021

Describe the bug

Here's the route components I've setup in my app and how I expect the URLs to resolve:

/routes/index.svelte -> / (homepage)
/routes/blog/index.svelte -> /blog
/routes/blog/[slug].svelte -> /blog/post-title-here

When I test this locally via npm run dev (or build + preview) everything works as expected. I can:

  1. I can navigate between paths using UI anchor tags
  2. Browse directly to each path in a new tab/window
  3. I can refresh the routes and remain on the desired page

Unfortunately, when I deploy to my server environment the blog post pages specifically have the following issues:

  1. If I navigate to the posts via a UI anchor tag -> works as expected
  2. If I try to copy/paste the full URL path into a new window/tab -> the homepage component shows instead
  3. If I try to browse to the post via the UI, then refresh -> same as number 2 above

NOTE: the URL I was trying to access remains in the URL bar in the browser, just visually the page shows the wrong content - the homepage instead of the slug/post page.

EDIT FYI the blog list is fetched dynamically from a headless Wordpress API. That means the blog list, the list of posts, will update and change over time. Likewise the blog post pages fetch the content of each page based on an ID provided as part of the route slug. I use SvelteKits module load() method along with a JS fetch call to retrieve the the content from the API, then rendered it on the [slug].svelte component page.

I'm assuming this may not be a SvelteKit-specific problem, but perhaps a bad configuration on my AWS server setup. Here's some details of how I configured the following:

  • Route53 (Domain/DNS): I have records setup to point to the Cloudfront Distribution
  • Cloudfront (content delivery): I have a distribution setup pointing the origin to the S3 (website) URL
  • S3 (hosting): just a basic bucket setup for static site hosting

Per Cloudfront, by default you will not be able to access subdirectories, which means SSR-mode cannot be used. However, after some research, I found that if you use the S3 -website- endpoint url instead of the auto-suggested S3 instance, then subdirectories will work as expected. Here's my source if you want to read more:

https://www.mark-gilbert.co.uk/serving-index-pages-from-non-root-locations-with-aws-cloudfront/

At this point everything is working on my site, minus the routing for the blog post pages. Any help or guidance is welcome. I'm happy to address any questions you might have.

Reproduction

As far as I'm aware the issue cannot be replicated using a local build of a SvelteKit app. For now I've linked directly to my site to show the issue in question.

These work. You can browse to each directly and refresh no problem:

These fail. Cannot browse to these URLs. Navigating to these pages from /blog, then refreshing, causes the homepage to show instead of the blog post content:

EDIT: I've reverted to SPA mode on our live site, so the issue will not be present currently.

Logs

No console errors are present when the route fails to resolve to the correct page.

System Info

System:
    OS: macOS 12.0.1
    CPU: (8) arm64 Apple M1
    Memory: 1.25 GB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 14.18.1 - /opt/homebrew/opt/node@14/bin/node
    npm: 6.14.15 - /opt/homebrew/opt/node@14/bin/npm
  Browsers:
    Chrome: 96.0.4664.55
    Safari: 15.1

Severity

annoyance

Additional Information

Here's what I'm seeing in the /dist directory after I build the app in SSR mode:

NOTE: showing only relevant files here:

index.html
/blog/index.html
dist/_app/pages/blog/_slug_.svelte-{hash}.js
dist/_app/pages/blog/index.svelte-{hash}.js

I'm kind of surprised not to see an /blog/slug.html or equivalent page.

For now I'm planning to work around this issue by using SPA mode. But I'd really love to use SSR if possible!

@Conduitry
Copy link
Member

If Kit can't find links to your pages when crawling the site it won't render them, but you can give additional entry points. See https://kit.svelte.dev/docs#configuration-prerender

@endigo9740
Copy link
Author

endigo9740 commented Nov 24, 2021

Thanks for the quick response. I've deployed changes to the live site above using the following svelte.config.js:

import preprocess from 'svelte-preprocess';
import adapter from '@sveltejs/adapter-static';

/** @type {import('@sveltejs/kit').Config} */
const config = {
	// Consult https://github.com/sveltejs/svelte-preprocess
	// for more information about preprocessors
    preprocess: preprocess({
        scss: {
            includePaths: ['./src/styles']
        },
    }),

	kit: {
		target: '#svelte',
        // https://github.com/sveltejs/kit/tree/master/packages/adapter-static
        adapter: adapter({
			pages: 'dist',
			assets: 'dist',
			fallback: null // 'index.html'
		}),
        prerender: {
            crawl: true,
            enabled: true,
            onError: 'fail'
        }
	}
};

export default config;

The documentation you linked is a bit thin, so perhaps I did something wrong here, but I'm not seeing any improvement. The issues described above persist.

I just realized I didn't include this information in the original post, so I'll edit to append this, but the blog list is fetched dynamically from a headless Wordpress API. That means the posts will update and change over time. Likewise the blog post pages fetch the content of each page based on an ID provided as part of the route slug. I use SvelteKits module load() method along with a JS fetch call to retrieve the the content from the API, then rendered it on the [slug].svelte component page.

Perhaps I misunderstand the concept, but doesn't this mean these pages can never be prerendered? As I understand it, prerendering happens at build time? Is that correct? Wouldn't prerendering the blog list/pages leave me with a stale blog that never updates?

@ivands
Copy link

ivands commented Jan 3, 2022

I got the same problem. Why doesn't the frontend realize it should render the correct page?

@endigo9740
Copy link
Author

endigo9740 commented Jan 3, 2022

Sorry I should have updated this sooner, but I had the issue addressed via a post on Reddit. Essentially S3 is not equip to handle SSR. You need to use something like EC2 to properly handle this. If your only option is S3, then opt for the SPA approach for now.

https://www.reddit.com/r/aws/comments/rdclh8/comment/ho0icxp/?utm_source=share&utm_medium=web2x&context=3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants