Skip to content

Unable to entirely disable prerendering #7899

@georgecrawford

Description

@georgecrawford

Describe the bug

Hi,

Forgive me if I've missed something! I'd like to run SvelteKit as a SSR-and-CSR solution, with no build-time prerendering.

From the docs, I can disable prerendering routes by adding a export const prerender = false; annotation to the top-level +layout.js. This seems to work.

I can also prevent the build process from crawling for entries to prerender (svelte.config.js):

        // Disable prerendering, as this is a dynamic app
        prerender: {
            crawl: false,
            entries: [],
        },

However, despite these two settings, I am still seeing an attempt to prerender when I run vite build:

#13 38.79 handleFeatureFlags (hooks/featureFlags.js) running for URL: http://sveltekit-prerender/[fallback]
...
#13 58.82 TypeError: Cannot destructure property 'CI_ENVIRONMENT_NAME' of 'env' as it is undefined.
#13 58.82     at reportError (file:///app/server/.svelte-kit/output/server/chunks/hooks.server.js:954:32)
#13 58.82     at Object.handleError (file:///app/server/.svelte-kit/output/server/chunks/hooks.server.js:1011:27)
#13 58.82     at Object.handle_error (file:///app/server/.svelte-kit/output/server/index.js:2369:35)
#13 58.82     at handle_error_and_jsonify (file:///app/server/.svelte-kit/output/server/index.js:243:20)
#13 58.82     at handle_fatal_error (file:///app/server/.svelte-kit/output/server/index.js:226:22)
#13 58.82     at respond (file:///app/server/.svelte-kit/output/server/index.js:2196:18)
#13 58.82     at async prerender (file:///app/server/node_modules/@sveltejs/kit/src/core/prerender/prerender.js:439:19)
...
#13 58.85 [vite-plugin-svelte-kit] Prerendering failed with code 1
#13 58.85 error during build:
#13 58.85 Error: Prerendering failed with code 1
#13 58.85     at ChildProcess.<anonymous> (file:///app/server/node_modules/@sveltejs/kit/src/exports/vite/index.js:462:15)
#13 58.85     at ChildProcess.emit (node:events:513:28)
#13 58.85     at ChildProcess.emit (node:domain:489:12)
#13 58.85     at Process.ChildProcess._handle.onexit (node:internal/child_process:293:12)

I've tracked this down to this code block:

	const rendered = await server.respond(new Request(config.prerender.origin + '/[fallback]'), {
		getClientAddress,
		prerendering: {
			fallback: true,
			dependencies: new Map()
		}
	});

	const file = `${config.outDir}/output/prerendered/fallback.html`;
	mkdirp(dirname(file));
	writeFileSync(file, await rendered.text());

Whereas prerendering known routes and other entries can be disabled with the above config, there doesn't seem to be a way to disable the rendering of the fallback.html file. This is a problem for anyone who wants to ship code in server hooks which doesn't work in the environment in which vite build is run.

Would it be possible to allow this fallback prerendering to be disabled? If not, it'd be great to understand why it's important (somewhere in the documentation), and I guess the only option is for the hooks to make use of $app/environment.building or similar to only conditionally run their logic?

Reproduction

https://stackblitz.com/edit/sveltejs-kit-template-default-x9vwcp

This project adds the following changes to the default https://node.new/sveltekit:

  • adds export const prerender = false; to src/routes/+layout.js
  • removes export const prerender = true; from all other routes
  • disables prerender crawling in svelte.config.js:
const config = {
	kit: {
		adapter: adapter(),

		// Disable prerendering, as this is a dynamic app
		prerender: {
			crawl: false,
			entries: []
		}
	}
};
  • adds a hooks.server.js file which relies on environment variables:
export async function handle({ event, resolve }) {
	const thisWillFail = new URL(process.env.UNDECLARED_ENV_VAR_DURING_BUILD);

	const response = await resolve(event);
	return response;
}

export async function handleError({ error, event }) {
	const thisWillFail = new URL(process.env.UNDECLARED_ENV_VAR_DURING_BUILD);

	return error;
}
  • modifies the npm run dev script to be "UNDECLARED_ENV_VAR_DURING_BUILD='http://testing' vite dev" so that local dev works

Running npm run build shows that an attempt to prerender the URL http://sveltekit-prerender/[fallback] is still made, and since the environment variable is not declared, the hooks cause the build to fail:

...
.svelte-kit/output/server/chunks/hooks.server.js                0.37 KiB
handle hook running for URL: http://sveltekit-prerender/[fallback]
TypeError [ERR_INVALID_URL]: Invalid URL
...
  input: 'undefined',
  code: 'ERR_INVALID_URL'
}
[vite-plugin-svelte-kit] Prerendering failed with code 1
error during build:
Error: Prerendering failed with code 1
...

One solution I've found for this is the following, in hooks.server.js:

import {building} from '$app/environment';

export const handle = building
    ? sequence()
    : sequence(
          handleLoggingAndMonitoring,
          handleCookieParsing,
          handleFeatureFlags,
          handleEnvVars,
          handleImageUrls,
          handleApiRequest,
          handleApiServices,
          handleSecurityHeaders
      );

Is this the recommended approach? If so, it still seems odd to me that I'm unable to disable prerendering across the board.

Logs

No response

System Info

System:
    OS: macOS 12.4
    CPU: (8) arm64 Apple M1 Pro
    Memory: 212.80 MB / 32.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 16.18.0 - /usr/local/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 8.19.2 - /usr/local/bin/npm
    Watchman: 2022.11.14.00 - /opt/homebrew/bin/watchman
  Browsers:
    Chrome: 107.0.5304.110
    Chrome Canary: 110.0.5443.0
    Firefox: 105.0.3
    Safari: 15.5
  npmPackages:
    @sveltejs/adapter-node: ^1.0.0-next.101 => 1.0.0-next.101
    @sveltejs/kit: ^1.0.0-next.570 => 1.0.0-next.570
    svelte: ^3.53.1 => 3.53.1

Severity

blocking all usage of SvelteKit

Additional Information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions