kit icon indicating copy to clipboard operation
kit copied to clipboard

Protected pre-rendered routes

Open hyunbinseo opened this issue 1 year ago • 2 comments

Describe the problem

I have an expensive static page which also happens to be a protected route.

I would love to prerender the page, but then it is not handled by SvelteKit.

Requests for static assets — which includes pages that were already prerendered — are not handled by SvelteKit.

https://kit.svelte.dev/docs/hooks#server-hooks-handle

Describe the proposed solution

  1. Add another page option in +page|layout.server.ts such as server: true.
  2. Add another value for the current prerender option such as protected.
  3. (Breaking) Convert the page prerender option into an object?
type Prerender = { enabled: boolean; protected: boolean };

https://kit.svelte.dev/docs/page-options#prerender

I am sure there are other usage then protected, but it seemed the most intuitive.

Alternatives considered

No response

Importance

would make my life easier

Additional Information

No response

hyunbinseo avatar Jan 22 '24 03:01 hyunbinseo

Will be implemented in https://github.com/sveltejs/kit/pull/13477

Unlike the handle hook, middleware runs on all requests, including for static assets and prerendered pages. If using server-side route resolution this means it runs prior to all navigations, no matter client- or server-side.

hyunbinseo avatar Mar 27 '25 06:03 hyunbinseo

Until middleware is implemented, the underlying static data can be protected using import.meta.glob in a server-only module:

// src/routes/[slug]/+page.server.ts

import { error } from '@sveltejs/kit';

const htmlModules = import.meta.glob<string>('./*.html', { query: '?raw', import: 'default' });

const loadHtml = (slug: string) => {
  const htmlLoader = htmlModules[`./${slug}.html`];
  if (!htmlLoader) error(404);
  return htmlLoader();
};

export const load = async ({ locals, params: { slug } }) => {
  if (!locals.session) error(401);
  return { html: await loadHtml(slug) };
};
<!-- src/routes/[slug]/lorem.html -->
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<!-- src/routes/[slug]/mauris.html -->
<p>Mauris sollicitudin dignissim rutrum. Pellentesque eu tellus et est vestibulum fermentum.</p>

It gets converted into a server chunk (unlike Vite static asset import)

// .svelte-kit/output/server/chunks/lorem.js
const lorem = "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>";
export {
  lorem as default
};

hyunbinseo avatar May 27 '25 02:05 hyunbinseo