Skip to content

adapter-cloudflare: allow disabling generation of fallback 404.html #9762

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

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/ninety-squids-explain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/adapter-cloudflare': minor
---

feat: allow disabling generation of `404.html`
11 changes: 11 additions & 0 deletions documentation/docs/25-build-and-deploy/60-adapter-cloudflare.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export default {

## Options

### Routes

The `routes` option allows you to customise the [`_routes.json`](https://developers.cloudflare.com/pages/platform/functions/routing/#create-a-_routesjson-file) file generated by `adapter-cloudflare`.

- `include` defines routes that will invoke a function, and defaults to `['/*']`
Expand All @@ -47,6 +49,15 @@ The `routes` option allows you to customise the [`_routes.json`](https://develop

You can have up to 100 `include` and `exclude` rules combined. Generally you can omit the `routes` options, but if (for example) your `<prerendered>` paths exceed that limit, you may find it helpful to manually create an `exclude` list that includes `'/articles/*'` instead of the auto-generated `['/articles/foo', '/articles/bar', '/articles/baz', ...]`.

### Generate 404

The `generate404` option allows you to specify whether a fallback `404.html` page will be generated.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should rename this to generateFallback so it better matches with the error message users get during build.

> Using @sveltejs/adapter-cloudflare
file:///Users/my-app/node_modules/@sveltejs/kit/src/core/postbuild/fallback.js:53
        throw new Error(`Could not create a fallback page — failed with status ${response.status}`);


The default value of `auto` will only generate a fallback `404.html` page if there are *any* prerendered pages.

You may want to set this to `false` if you have a fully dynamic app that does not prerender pages during build time.
Comment on lines +56 to +58
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The default value of `auto` will only generate a fallback `404.html` page if there are *any* prerendered pages.
You may want to set this to `false` if you have a fully dynamic app that does not prerender pages during build time.
The default value of `auto` or `true` will generate a fallback page if prerendering occurs. This will be generated from your [error page](https://kit.svelte.dev/docs/routing#error).

You may want to set this to false if you have a fully dynamic app that does not prerender pages during build time.

I don't think we need to say this, as auto would prevent this anyway? If we want to mention false then we could say something like Set this option to false to prevent generating a fallback.



## Deployment

Please follow the [Get Started Guide](https://developers.cloudflare.com/pages/get-started) for Cloudflare Pages to begin.
Expand Down
9 changes: 9 additions & 0 deletions packages/adapter-cloudflare/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ export interface AdapterOptions {
*/
exclude?: string[];
};

/**
* Should a fallback 404.html be generated?
*
* 'auto' will only generate a fallback page if there are any prerendered pages
*
* @default auto
*/
generate404?: boolean | 'auto';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be named something like fallback?

}

export interface RoutesJSONSpec {
Expand Down
20 changes: 17 additions & 3 deletions packages/adapter-cloudflare/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,27 @@ export default function (options = {}) {
builder.rimraf(tmp);
builder.mkdirp(tmp);

// generate 404.html first which can then be overridden by prerendering, if the user defined such a page
Copy link
Member

@eltigerchino eltigerchino Aug 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we still account for user-defined 404.html pages before generating it for them? Right now we would be overwriting them as it's generated after the prererendered pages.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea it might be better to move this back about builder.writePrerendered line

await builder.generateFallback(path.join(dest, '404.html'));

const dest_dir = `${dest}${builder.config.kit.paths.base}`;
const written_files = builder.writeClient(dest_dir);
builder.writePrerendered(dest_dir);

const generate404 = options.generate404 ?? 'auto';

if (
(generate404 === 'auto' && builder.prerendered.paths.length > 0) ||
generate404 === true
) {
await builder.generateFallback(path.join(dest, '404.html'));
} else {
writeFileSync(
path.join(dest_dir, builder.config.kit.appDir, '404.html'),
builder
.loadErrorPage()
.replace(/%sveltekit\.status%/g, '404')
.replace(/%sveltekit\.error\.message%/g, 'Not found')
);
}

const relativePath = path.posix.relative(tmp, builder.getServerDirectory());

writeFileSync(
Expand Down
5 changes: 5 additions & 0 deletions packages/kit/src/core/adapt/builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { get_route_segments } from '../../utils/routing.js';
import { get_env } from '../../exports/vite/utils.js';
import generate_fallback from '../postbuild/fallback.js';
import { write } from '../sync/utils.js';
import { load_error_page } from '../config/index.js';
import { list_files } from '../utils.js';

const pipe = promisify(pipeline);
Expand Down Expand Up @@ -189,6 +190,10 @@ export function create_builder({
return build_data.app_path;
},

loadErrorPage: () => {
return load_error_page(config);
},

writeClient(dest) {
return copy(`${config.kit.outDir}/output/client`, dest, {
// avoid making vite build artefacts public
Expand Down
3 changes: 3 additions & 0 deletions packages/kit/src/exports/public.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ export interface Builder {
/** Create `dir` and any required parent directories. */
mkdirp(dir: string): void;

/** Gets the content of the simple error page (src/error.html) */
loadErrorPage(): string;

/** The fully resolved `svelte.config.js`. */
config: ValidatedConfig;
/** Information about prerendered pages and assets, if any. */
Expand Down