diff --git a/dev/check-links.mjs b/dev/check-links.mjs index e37c940f7..7b232eda0 100644 --- a/dev/check-links.mjs +++ b/dev/check-links.mjs @@ -219,11 +219,11 @@ function buildPathMap() { }; } -// Source route -> destination of src/data/redirects.ts. The middleware uses the -// first rule whose source equals the requested path, so first entry wins here too. +// Source route -> destination of src/data/redirects.js. The first rule whose +// source equals the requested path wins here too. function loadRedirects() { const redirects = new Map(); - const source = fs.readFileSync(path.join(ROOT_DIR, 'src/data/redirects.ts'), 'utf-8'); + const source = fs.readFileSync(path.join(ROOT_DIR, 'src/data/redirects.js'), 'utf-8'); const ruleRegex = /source:\s*(['"])(.*?)\1,\s*destination:\s*(['"])(.*?)\3/gs; for (const [, , from, , to] of source.matchAll(ruleRegex)) { if (!redirects.has(from)) redirects.set(from, to); diff --git a/next.config.js b/next.config.js index 8e71169ab..2ca4c8f3a 100644 --- a/next.config.js +++ b/next.config.js @@ -1,7 +1,31 @@ const {withContentlayer} = require('next-contentlayer'); const {execSync} = require('child_process'); +const {updatedRedirectsData} = require('./src/data/redirects.js'); /** @type {import('next').NextConfig} */ +function createStaticRedirects() { + const seenSources = new Set(); + const redirects = []; + + for (const redirect of updatedRedirectsData) { + if ( + redirect.source.includes('#') || + redirect.source.includes('?') || + seenSources.has(redirect.source) + ) { + continue; + } + + seenSources.add(redirect.source); + redirects.push({...redirect, permanent: false}); + } + + return redirects; +} + +const staticRedirects = createStaticRedirects(); +console.log(`Configured ${staticRedirects.length} static redirects`); + const nextConfig = { reactStrictMode: true, swcMinify: true, @@ -15,7 +39,11 @@ const nextConfig = { env: { NEXT_PUBLIC_DOCS_BASE_PATH: process.env.VERCEL_ENV === 'production' ? '/docs' : '' - } + }, + redirects: async () => staticRedirects, + rewrites: async () => ({ + beforeFiles: [{source: '/:path*.md', destination: '/api/md/:path*'}] + }) }; module.exports = async () => { diff --git a/src/data/redirects.ts b/src/data/redirects.js similarity index 99% rename from src/data/redirects.ts rename to src/data/redirects.js index c1a548241..4b4d640f7 100644 --- a/src/data/redirects.ts +++ b/src/data/redirects.js @@ -1,5 +1,3 @@ -import {TECHNICAL_CHANGELOG_RSS_URL} from './constants'; - const redirectsData = [ { source: '/integration/img/disable_extension.png', @@ -5839,7 +5837,7 @@ const redirectsData = [ // This redirect preserves existing RSS subscriptions { source: '/technical-changelog.rss', - destination: TECHNICAL_CHANGELOG_RSS_URL + destination: 'https://sourcegraph.com/changelog/technical-changelog.rss' }, // Self-hosted update pages moved to /changelog/self-hosted/ { diff --git a/src/middleware.ts b/src/middleware.ts index c852a662f..b70fa136c 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -4,7 +4,7 @@ import docsConfig from '../docs.config.js'; import {TECHNICAL_CHANGELOG_RSS_URL} from './data/constants'; -const {updatedRedirectsData} = require('./data/redirects.ts'); +const {updatedRedirectsData} = require('./data/redirects.js'); function createRedirectUrl( request: NextRequest, @@ -59,24 +59,6 @@ export function middleware(request: NextRequest) { const path = request.nextUrl.pathname; const pathWithoutBase = path.replace('/docs', ''); - // Handle .md suffix - return raw markdown - if (pathWithoutBase.endsWith('.md')) { - const docPath = pathWithoutBase.replace(/\.md$/, ''); - const url = request.nextUrl.clone(); - url.pathname = `/api/md${docPath}`; - return NextResponse.rewrite(url); - } - - // Handle base redirects from redirects.ts - const redirect = updatedRedirectsData.find( - (r: any) => r.source === pathWithoutBase - ); - if (redirect) { - return NextResponse.redirect( - createRedirectUrl(request, redirect.destination, path) - ); - } - // Handle latest version without path - redirect to main docs const latestVersionOnlyMatch = pathWithoutBase.match( `^\/(?:v\/|@)${docsConfig.DOCS_LATEST_VERSION}\/?$` @@ -146,5 +128,5 @@ export function middleware(request: NextRequest) { } export const config = { - matcher: ['/((?!api/md|_next/static|_next/image|assets|favicon.ico|sw.js).*)'] + matcher: ['/v/:path*', '/@:path*', '/changelog.rss'] };