From e0ed1bdbf61187c5bd5be26dbdd13ca46d708ead Mon Sep 17 00:00:00 2001 From: Emanuele Stoppa Date: Tue, 14 Jan 2025 10:36:05 +0000 Subject: [PATCH] add changeset --- .changeset/light-pants-smoke.md | 20 +++++++++++++ packages/astro/src/types/public/config.ts | 24 ++++++++++++---- packages/underscore-redirects/src/astro.ts | 33 +++++++++++----------- 3 files changed, 56 insertions(+), 21 deletions(-) create mode 100644 .changeset/light-pants-smoke.md diff --git a/.changeset/light-pants-smoke.md b/.changeset/light-pants-smoke.md new file mode 100644 index 000000000000..aad756ca500c --- /dev/null +++ b/.changeset/light-pants-smoke.md @@ -0,0 +1,20 @@ +--- +'astro': minor +--- + +Adds support for external redirects `astro.config.mjs`: + +```js +// astro.config.mjs +import {defineConfig} from "astro/config" + +export default defineConfig({ + redirects: { + "/blog": "https://example.com/blog", + "/news": { + status: 302, + destination: "https://example.com/news" + } + } +}) +``` diff --git a/packages/astro/src/types/public/config.ts b/packages/astro/src/types/public/config.ts index 635e57798c66..c86c74961916 100644 --- a/packages/astro/src/types/public/config.ts +++ b/packages/astro/src/types/public/config.ts @@ -264,16 +264,16 @@ export interface ViteUserConfig extends OriginalViteUserConfig { * and the value is the path to redirect to. * * You can redirect both static and dynamic routes, but only to the same kind of route. - * For example you cannot have a `'/article': '/blog/[...slug]'` redirect. + * For example, you cannot have a `'/article': '/blog/[...slug]'` redirect. * * * ```js - * { + * export default defineConfig({ * redirects: { * '/old': '/new', * '/blog/[...slug]': '/articles/[...slug]', * } - * } + * }) * ``` * * @@ -287,14 +287,28 @@ export interface ViteUserConfig extends OriginalViteUserConfig { * You can customize the [redirection status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages) using an object in the redirect config: * * ```js - * { + * export default defineConfig({ * redirects: { * '/other': { * status: 302, * destination: '/place', * }, * } - * } + * }) + * ``` + * + * Since **v5.2.0**, the property accepts external URLs: + * + * ```js + * export default defineConfig({ + * redirects: { + * '/blog': 'https://example.com/blog', + * '/news': { + * status: 302, + * destination: 'https://example.com/news' + * } + * } + * }) * ``` */ redirects?: Record; diff --git a/packages/underscore-redirects/src/astro.ts b/packages/underscore-redirects/src/astro.ts index bd3e3b2ea346..83347fcdc6a3 100644 --- a/packages/underscore-redirects/src/astro.ts +++ b/packages/underscore-redirects/src/astro.ts @@ -36,23 +36,23 @@ export function createRedirectsFromAstroRoutes({ dir, buildOutput, assets, -}: CreateRedirectsFromAstroRoutesParams) { +}: CreateRedirectsFromAstroRoutesParams): Redirects { const base = config.base && config.base !== '/' ? config.base.endsWith('/') ? config.base.slice(0, -1) : config.base : ''; - const _redirects = new Redirects(); + const redirects = new Redirects(); for (const [route, dynamicTarget = ''] of routeToDynamicTargetMap) { const distURL = assets.get(route.pattern); // A route with a `pathname` is as static route. if (route.pathname) { if (route.redirect) { - // A redirect route without dynami§c parts. Get the redirect status + // A redirect route without dynamic parts. Get the redirect status // from the user if provided. - _redirects.add({ + redirects.add({ dynamic: false, input: `${base}${route.pathname}`, target: typeof route.redirect === 'object' ? route.redirect.destination : route.redirect, @@ -65,8 +65,10 @@ export function createRedirectsFromAstroRoutes({ // If this is a static build we don't want to add redirects to the HTML file. if (buildOutput === 'static') { continue; - } else if (distURL) { - _redirects.add({ + } + + if (distURL) { + redirects.add({ dynamic: false, input: `${base}${route.pathname}`, target: prependForwardSlash(distURL.toString().replace(dir.toString(), '')), @@ -74,7 +76,7 @@ export function createRedirectsFromAstroRoutes({ weight: 2, }); } else { - _redirects.add({ + redirects.add({ dynamic: false, input: `${base}${route.pathname}`, target: dynamicTarget, @@ -83,7 +85,7 @@ export function createRedirectsFromAstroRoutes({ }); if (route.pattern === '/404') { - _redirects.add({ + redirects.add({ dynamic: true, input: '/*', target: dynamicTarget, @@ -100,14 +102,13 @@ export function createRedirectsFromAstroRoutes({ // This route was prerendered and should be forwarded to the HTML file. if (distURL) { const targetRoute = route.redirectRoute ?? route; - const targetPattern = generateDynamicPattern(targetRoute); - let target = targetPattern; + let target = generateDynamicPattern(targetRoute); if (config.build.format === 'directory') { target = pathJoin(target, 'index.html'); } else { target += '.html'; } - _redirects.add({ + redirects.add({ dynamic: true, input: `${base}${pattern}`, target, @@ -115,7 +116,7 @@ export function createRedirectsFromAstroRoutes({ weight: 1, }); } else { - _redirects.add({ + redirects.add({ dynamic: true, input: `${base}${pattern}`, target: dynamicTarget, @@ -126,7 +127,7 @@ export function createRedirectsFromAstroRoutes({ } } - return _redirects; + return redirects; } /** @@ -135,7 +136,7 @@ export function createRedirectsFromAstroRoutes({ * With stars replacing spread and :id syntax replacing [id] */ function generateDynamicPattern(route: IntegrationResolvedRoute) { - const pattern = + return ( '/' + route.segments .map(([part]) => { @@ -150,8 +151,8 @@ function generateDynamicPattern(route: IntegrationResolvedRoute) { return part.content; } }) - .join('/'); - return pattern; + .join('/') + ); } function prependForwardSlash(str: string) {