Skip to content

Commit

Permalink
add trailing slash redirect middleware to adapter-node (#8857)
Browse files Browse the repository at this point in the history
* add trailing slash redirect middleware

* add changeset

* skip middleware where possible

* dont add ? to URLs

* minor tweak

---------

Co-authored-by: Rich Harris <hello@rich-harris.dev>
  • Loading branch information
eltigerchino and Rich-Harris committed Feb 2, 2023
1 parent a96c966 commit 288bfe3
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/warm-bananas-sneeze.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/adapter-node': patch
---

fix: correctly redirect trailing slashes for `adapter-node`
2 changes: 2 additions & 0 deletions packages/adapter-node/ambient.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ declare module 'HANDLER' {

declare module 'MANIFEST' {
import { SSRManifest } from '@sveltejs/kit';

export const manifest: SSRManifest;
export const prerendered: Set<string>;
}

declare module 'SERVER' {
Expand Down
7 changes: 4 additions & 3 deletions packages/adapter-node/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { readFileSync, writeFileSync } from 'fs';
import { fileURLToPath } from 'url';
import { readFileSync, writeFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { rollup } from 'rollup';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
Expand Down Expand Up @@ -39,7 +39,8 @@ export default function (opts = {}) {

writeFileSync(
`${tmp}/manifest.js`,
`export const manifest = ${builder.generateManifest({ relativePath: './' })};`
`export const manifest = ${builder.generateManifest({ relativePath: './' })};\n\n` +
`export const prerendered = new Set(${JSON.stringify(builder.prerendered.paths)});\n`
);

const pkg = JSON.parse(readFileSync('package.json', 'utf8'));
Expand Down
41 changes: 36 additions & 5 deletions packages/adapter-node/src/handler.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import './shims';
import fs from 'fs';
import path from 'path';
import fs from 'node:fs';
import path from 'node:path';
import sirv from 'sirv';
import { fileURLToPath } from 'url';
import { fileURLToPath } from 'node:url';
import { getRequest, setResponse } from '@sveltejs/kit/node';
import { Server } from 'SERVER';
import { manifest } from 'MANIFEST';
import { manifest, prerendered } from 'MANIFEST';
import { env } from 'ENV';

/* global ENV_PREFIX */
Expand Down Expand Up @@ -44,8 +44,39 @@ function serve(path, client = false) {
);
}

// required because the static file server ignores trailing slashes
/** @returns {import('polka').Middleware} */
function serve_prerendered() {
const handler = serve(path.join(dir, 'prerendered'));

return (req, res, next) => {
let pathname = req.path;

try {
pathname = decodeURIComponent(pathname);
} catch {
// ignore invalid URI
}

if (prerendered.has(pathname)) {
return handler(req, res, next);
}

// remove or add trailing slash as appropriate
let location = pathname.at(-1) === '/' ? pathname.slice(0, -1) : pathname + '/';
if (prerendered.has(location)) {
const search = req.url.split('?')[1];
if (search) location += `?${search}`;
res.writeHead(308, { location }).end();
} else {
next();
}
};
}

/** @type {import('polka').Middleware} */
const ssr = async (req, res) => {
/** @type {Request | undefined} */
let request;

try {
Expand Down Expand Up @@ -139,7 +170,7 @@ export const handler = sequence(
[
serve(path.join(dir, 'client'), true),
serve(path.join(dir, 'static')),
serve(path.join(dir, 'prerendered')),
serve_prerendered(),
ssr
].filter(Boolean)
);

0 comments on commit 288bfe3

Please sign in to comment.