diff --git a/apps/svelte.dev/src/lib/server/content.ts b/apps/svelte.dev/src/lib/server/content.ts index faa960ec07..45f0d4b0b2 100644 --- a/apps/svelte.dev/src/lib/server/content.ts +++ b/apps/svelte.dev/src/lib/server/content.ts @@ -60,16 +60,16 @@ export const blog_posts = index.blog.children return a.date < b.date ? 1 : -1; }); +export function remove_section(slug: string) { + return slug.replace(/\/[^/]+(\/[^/]+)$/g, '$1'); +} + /** * Create docs index, which is basically the same structure as the original index * but with adjusted slugs (the section part is omitted for cleaner URLs), separated * topics/pages and next/prev adjusted so that they don't point to different topics. */ function create_docs() { - function remove_section(slug: string) { - return slug.replace(/\/[^/]+(\/[^/]+)$/g, '$1'); - } - let docs: { /** The top level entries/packages: svelte/kit/etc. Key is the topic */ topics: Record; diff --git a/apps/svelte.dev/src/routes/e/[code]/+page.server.ts b/apps/svelte.dev/src/routes/e/[code]/+page.server.ts new file mode 100644 index 0000000000..a564c600f0 --- /dev/null +++ b/apps/svelte.dev/src/routes/e/[code]/+page.server.ts @@ -0,0 +1,40 @@ +import { remove_section } from '$lib/server/content'; +import { error, redirect } from '@sveltejs/kit'; + +// All links to warnings/errors from the Svelte compiler/runtime go through this page in order to have stable references +// (i.e. we can move codes between warnings/errors/different pages or even adjust codes without breaking links). + +// Right now we can't prerender this because we would hit a "too many routes" error on Vercel, +// for which we need to implement https://github.com/sveltejs/kit/issues/9032 +// const reference = index['docs/svelte/reference'].children.filter( +// (child) => child.slug.endsWith('-errors') || child.slug.endsWith('-warnings') +// ); +// +// export const prerender = true; +// +// export function entries() { +// return reference.flatMap((page) => +// [...page.body.matchAll(/(^|\n)### (\w+)/g)].map(([, , code]) => ({ code })) +// ); +// } + +export async function load({ params, fetch }) { + const codes: Record> = await fetch('/e/tmp/codes.json').then( + (r) => r.json() + ); + + for (const url of Object.keys(codes)) { + const page = codes[url]; + for (const [h2, h3] of Object.entries(page)) { + if (h3.includes(params.code)) { + if (h2) { + redirect(307, `/${remove_section(url)}#${h2}-${params.code}`); + } else { + redirect(307, `/${remove_section(url)}#${params.code}`); + } + } + } + } + + error(404, 'Not found'); +} diff --git a/apps/svelte.dev/src/routes/e/tmp/codes.json/+server.ts b/apps/svelte.dev/src/routes/e/tmp/codes.json/+server.ts new file mode 100644 index 0000000000..05685f33e0 --- /dev/null +++ b/apps/svelte.dev/src/routes/e/tmp/codes.json/+server.ts @@ -0,0 +1,39 @@ +import { index } from '$lib/server/content'; +import { json } from '@sveltejs/kit'; + +// Temporary workaround for the problem described in [code]/+page.server.ts +// In a nested folder because of https://github.com/sveltejs/kit/issues/12778 + +const reference = index['docs/svelte/reference'].children.filter( + (child) => child.slug.endsWith('-errors') || child.slug.endsWith('-warnings') +); + +// Since codes are not top level section we gotta jump through some hoops to get the right hash + +const codes: Record> = {}; + +for (const page of reference) { + const grouped: Record = {}; + const sections = page.body.split(/(^|\n)## /g).slice(1); + + for (const section of sections) { + const lines = section.slice(section.startsWith('\n') ? 1 : 0).split('\n'); + const h2 = lines.shift()?.trim(); + + const h3_titles = lines + .filter((line) => line.startsWith('### ')) + .map((line) => line.slice(4).trim()); + + if (h3_titles.length > 0) { + grouped[page.sections.find((s) => s.title === h2)?.slug ?? ''] = h3_titles; + } + } + + codes[page.slug] = grouped; +} + +export const prerender = true; + +export function GET() { + return json(codes); +}