Skip to content

Commit

Permalink
feat: Add a speedier script tag for prerendered redirects (#9911)
Browse files Browse the repository at this point in the history
* feat: Add a script redirect to prerendered pages

* changeset

* Update .changeset/hungry-rocks-hunt.md

Co-authored-by: Simon H <[email protected]>

* fix test

* feat: Update string escaping

* Update .changeset/hungry-rocks-hunt.md

Co-authored-by: Conduitry <[email protected]>

---------

Co-authored-by: Simon H <[email protected]>
Co-authored-by: Conduitry <[email protected]>
  • Loading branch information
3 people authored May 16, 2023
1 parent b061166 commit a81106b
Show file tree
Hide file tree
Showing 9 changed files with 36 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/hungry-rocks-hunt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

perf: add `<script>` to prerendered redirects for faster redirects
7 changes: 6 additions & 1 deletion packages/kit/src/core/postbuild/prerender.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { get_route_segments } from '../../utils/routing.js';
import { queue } from './queue.js';
import { crawl } from './crawl.js';
import { forked } from '../../utils/fork.js';
import * as devalue from 'devalue';

export default forked(import.meta.url, prerender);

Expand Down Expand Up @@ -340,7 +341,11 @@ async function prerender({ out, manifest_path, metadata, verbose, env }) {

writeFileSync(
dest,
`<meta http-equiv="refresh" content=${escape_html_attr(`0;url=${location}`)}>`
`<script>location.href=${devalue.uneval(
location
)};</script><meta http-equiv="refresh" content=${escape_html_attr(
`0;url=${location}`
)}>`
);

written.add(file);
Expand Down
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { redirect } from '@sveltejs/kit';

/** @type {import('@sveltejs/kit').Load} */
export function load() {
throw redirect(301, '/env');
}
Empty file.
Empty file.
19 changes: 15 additions & 4 deletions packages/kit/test/prerendering/basics/test/tests.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@ test('renders a redirect', () => {
const content = read('redirect.html');
assert.equal(
content,
'<meta http-equiv="refresh" content="0;url=https://example.com/redirected">'
'<script>location.href="https:\\u002F\\u002Fexample.com\\u002Fredirected";</script><meta http-equiv="refresh" content="0;url=https://example.com/redirected">'
);
});

test('renders a server-side redirect', () => {
const html = read('redirect-server.html');
assert.equal(html, '<meta http-equiv="refresh" content="0;url=https://example.com/redirected">');
assert.equal(
html,
'<script>location.href="https:\\u002F\\u002Fexample.com\\u002Fredirected";</script><meta http-equiv="refresh" content="0;url=https://example.com/redirected">'
);

const data = JSON.parse(read('redirect-server/__data.json'));

Expand All @@ -36,15 +39,23 @@ test('does not double-encode redirect locations', () => {
const content = read('redirect-encoded.html');
assert.equal(
content,
'<meta http-equiv="refresh" content="0;url=https://example.com/redirected?returnTo=%2Ffoo%3Fbar%3Dbaz">'
'<script>location.href="https:\\u002F\\u002Fexample.com\\u002Fredirected?returnTo=%2Ffoo%3Fbar%3Dbaz";</script><meta http-equiv="refresh" content="0;url=https://example.com/redirected?returnTo=%2Ffoo%3Fbar%3Dbaz">'
);
});

test('escapes characters in redirect', () => {
const content = read('redirect-malicious.html');
assert.equal(
content,
'<meta http-equiv="refresh" content="0;url=https://example.com/</script>alert(&quot;pwned&quot;)">'
'<script>location.href="https:\\u002F\\u002Fexample.com\\u002F\\u003C\\u002Fscript\\u003Ealert(\\"pwned\\")";</script><meta http-equiv="refresh" content="0;url=https://example.com/</script>alert(&quot;pwned&quot;)">'
);
});

test('renders a relative redirect', () => {
const content = read('redirect-relative.html');
assert.equal(
content,
'<script>location.href="\\u002Fenv";</script><meta http-equiv="refresh" content="0;url=/env">'
);
});

Expand Down
5 changes: 4 additions & 1 deletion packages/kit/test/prerendering/paths-base/test/tests.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ test('prerenders /path-base', () => {

test('prerenders /path-base/redirect', () => {
const content = read('redirect.html');
assert.equal(content, '<meta http-equiv="refresh" content="0;url=/path-base/dynamic/foo">');
assert.equal(
content,
'<script>location.href="\\u002Fpath-base\\u002Fdynamic\\u002Ffoo";</script><meta http-equiv="refresh" content="0;url=/path-base/dynamic/foo">'
);
});

test('prerenders /path-base/dynamic/foo', () => {
Expand Down

0 comments on commit a81106b

Please sign in to comment.