From fb2185083c2b6736430d0910bf57977e3e4a9c13 Mon Sep 17 00:00:00 2001 From: Ax333l Date: Fri, 4 Nov 2022 19:20:33 +0100 Subject: [PATCH] feat: add vercel routes config generator This is so we do not need to force trailing slashes. --- src/_vercel-moment.js | 82 +++++++++++++++++++++++++++++++++++++++++++ svelte.config.js | 8 ++--- 2 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 src/_vercel-moment.js diff --git a/src/_vercel-moment.js b/src/_vercel-moment.js new file mode 100644 index 0000000..01e681c --- /dev/null +++ b/src/_vercel-moment.js @@ -0,0 +1,82 @@ +import fs from 'fs'; + +// This code was stolen from https://github.com/sveltejs/kit/blob/master/packages/adapter-static/platforms.js + +// sveltekit does things like this instead of actually just using ts for some reason. +/** @param {import('@sveltejs/kit').Builder} builder */ +function vercel_routes(builder) { + /** @type {any[]} */ + const routes = [ + { + src: `/${builder.config.kit.appDir}/immutable/.+`, + headers: { + 'cache-control': 'public, immutable, max-age=31536000' + } + } + ]; + + // explicit redirects + for (const [src, redirect] of builder.prerendered.redirects) { + routes.push({ + src, + headers: { + Location: redirect.location + }, + status: redirect.status + }); + } + + // prerendered pages + for (const [src, page] of builder.prerendered.pages) { + routes.push({ + src, + dest: `${builder.config.kit.appDir}/prerendered/${page.file}` + }); + } + + // implicit redirects (trailing slashes) + for (const [src] of builder.prerendered.pages) { + if (src !== '/') { + routes.push({ + src: src.endsWith('/') ? src.slice(0, -1) : src + '/', + headers: { + location: src + }, + status: 308 + }); + } + } + + routes.push({ + handle: 'filesystem' + }); + + return routes; +} + +export function wrap(adapter, opts) { + if (!process.env.VERCEL) { + // we don't have to bother :) + return adapter(opts); + } + + // Not exactly what adapter-static does, but it works. + opts.pages = '.vercel/output/static'; + + adapter = adapter(opts); + + const adapt_fn = adapter.adapt; + adapter.adapt = async (builder) => { + const result = await adapt_fn(builder); + fs.writeFileSync( + '.vercel/output/config.json', + JSON.stringify({ + version: 3, + routes: vercel_routes(builder) + }) + ); + return result; + } + + return adapter; +} diff --git a/svelte.config.js b/svelte.config.js index 55305a6..b5327fd 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -1,6 +1,8 @@ import adapter from '@sveltejs/adapter-static'; import preprocess from 'svelte-preprocess'; +import { wrap } from './src/_vercel-moment.js'; + /** @type {import('@sveltejs/kit').Config} */ const config = { // Consult https://github.com/sveltejs/svelte-preprocess @@ -9,13 +11,11 @@ const config = { kit: { // adapter-static has vercel detection, but that does not let you set a custom 404 page easily. - // Instead, we have to disable it and set trailing slash to always. - adapter: adapter({ + // Instead, we have to use a wrapper that generates a vercel config if on vercel... + adapter: wrap(adapter, { pages: "public", fallback: "404.html" }), - - trailingSlash: 'always' } };