Skip to content

Commit beacfef

Browse files
committed
feat: add stable route for all warning/error codes
This establishes a new route `e/[code]` which serves as a stable reference for all of our warning/error codes. All links to warnings/errors from the Svelte compiler/runtime should go through this route in order to have stable references. That way we can move codes between warnings/errors/different pages or even adjust codes without breaking links. Part of sveltejs/svelte#11305
1 parent fb84f19 commit beacfef

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

apps/svelte.dev/src/lib/server/content.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,16 @@ export const blog_posts = index.blog.children
6060
return a.date < b.date ? 1 : -1;
6161
});
6262

63+
export function remove_section(slug: string) {
64+
return slug.replace(/\/[^/]+(\/[^/]+)$/g, '$1');
65+
}
66+
6367
/**
6468
* Create docs index, which is basically the same structure as the original index
6569
* but with adjusted slugs (the section part is omitted for cleaner URLs), separated
6670
* topics/pages and next/prev adjusted so that they don't point to different topics.
6771
*/
6872
function create_docs() {
69-
function remove_section(slug: string) {
70-
return slug.replace(/\/[^/]+(\/[^/]+)$/g, '$1');
71-
}
72-
7373
let docs: {
7474
/** The top level entries/packages: svelte/kit/etc. Key is the topic */
7575
topics: Record<string, Document>;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { index, remove_section } from '$lib/server/content';
2+
import { error, redirect } from '@sveltejs/kit';
3+
4+
// All links to warnings/errors from the Svelte compiler/runtime go through this page in order to have stable references
5+
// (i.e. we can move codes between warnings/errors/different pages or even adjust codes without breaking links).
6+
const reference = index['docs/svelte/reference'].children.filter(
7+
(child) => child.slug.endsWith('-errors') || child.slug.endsWith('-warnings')
8+
);
9+
10+
export const prerender = true;
11+
12+
export function load({ params }) {
13+
// Since codes are not top level section we gotta jump through some hoops to get the right hash
14+
for (const page of reference) {
15+
const idx = page.body.indexOf(`### ${params.code}`);
16+
if (idx === -1) continue;
17+
18+
const slug_idx = page.body.lastIndexOf('\n## ', idx);
19+
20+
if (slug_idx > 0 || page.body.startsWith(`## `)) {
21+
const title = page.body.slice(slug_idx + 4, page.body.indexOf('\n', slug_idx + 4)).trim();
22+
const slug = page.sections.find((s) => s.title === title)?.slug;
23+
24+
if (!slug) {
25+
throw new Error(
26+
`Internal Error: Could not find previous title for code ${params.code} on ${page.slug}`
27+
);
28+
}
29+
30+
redirect(307, `/${remove_section(page.slug)}#${slug}-${params.code}`);
31+
} else {
32+
redirect(307, `/${remove_section(page.slug)}#${params.code}`);
33+
}
34+
}
35+
36+
error(404, 'Not found');
37+
}

0 commit comments

Comments
 (0)