Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 1 addition & 25 deletions packages/angular/build/src/utils/server-rendering/prerender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
WritableSerializableRouteTreeNode,
} from './models';
import type { RenderWorkerData } from './render-worker';
import { generateRedirectStaticPage } from './utils';

type PrerenderOptions = NormalizedApplicationBuildOptions['prerenderOptions'];
type AppShellOptions = NormalizedApplicationBuildOptions['appShellOptions'];
Expand Down Expand Up @@ -380,28 +381,3 @@ function addTrailingSlash(url: string): string {
function removeLeadingSlash(value: string): string {
return value[0] === '/' ? value.slice(1) : value;
}

/**
* Generates a static HTML page with a meta refresh tag to redirect the user to a specified URL.
*
* This function creates a simple HTML page that performs a redirect using a meta tag.
* It includes a fallback link in case the meta-refresh doesn't work.
*
* @param url - The URL to which the page should redirect.
* @returns The HTML content of the static redirect page.
*/
function generateRedirectStaticPage(url: string): string {
return `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Redirecting</title>
<meta http-equiv="refresh" content="0; url=${url}">
</head>
<body>
<pre>Redirecting to <a href="${url}">${url}</a></pre>
</body>
</html>
`.trim();
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type { ESMInMemoryFileLoaderWorkerData } from './esm-in-memory-loader/loa
import { patchFetchToLoadInMemoryAssets } from './fetch-patch';
import { DEFAULT_URL, launchServer } from './launch-server';
import { loadEsmModuleFromMemory } from './load-esm-from-memory';
import { generateRedirectStaticPage } from './utils';

export interface RenderWorkerData extends ESMInMemoryFileLoaderWorkerData {
assetFiles: Record</** Destination */ string, /** Source */ string>;
Expand Down Expand Up @@ -48,7 +49,13 @@ async function renderPage({ url }: RenderOptions): Promise<string | null> {
new Request(new URL(url, serverURL), { signal: AbortSignal.timeout(30_000) }),
);

return response ? response.text() : null;
if (!response) {
return null;
}

const location = response.headers.get('Location');

return location ? generateRedirectStaticPage(location) : response.text();
}

async function initialize() {
Expand Down
25 changes: 25 additions & 0 deletions packages/angular/build/src/utils/server-rendering/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,28 @@ export function isSsrRequestHandler(
): value is ReturnType<typeof createRequestHandler> {
return typeof value === 'function' && '__ng_request_handler__' in value;
}

/**
* Generates a static HTML page with a meta refresh tag to redirect the user to a specified URL.
*
* This function creates a simple HTML page that performs a redirect using a meta tag.
* It includes a fallback link in case the meta-refresh doesn't work.
*
* @param url - The URL to which the page should redirect.
* @returns The HTML content of the static redirect page.
*/
export function generateRedirectStaticPage(url: string): string {
return `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Redirecting</title>
<meta http-equiv="refresh" content="0; url=${url}">
</head>
<body>
<pre>Redirecting to <a href="${url}">${url}</a></pre>
</body>
</html>
`.trim();
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ export default async function () {
await writeFile(
'src/app/app.routes.ts',
`
import { Routes } from '@angular/router';
import { inject } from '@angular/core';
import { Routes, Router } from '@angular/router';
import { Home } from './home/home';
import { Ssg } from './ssg/ssg';
import { SsgWithParams } from './ssg-with-params/ssg-with-params';
Expand All @@ -47,6 +48,12 @@ export default async function () {
path: 'ssg-redirect',
redirectTo: 'ssg'
},
{
path: 'ssg-redirect-via-guard',
canActivate: [() => {
return inject(Router).createUrlTree(['ssg'], { queryParams: { foo: 'bar' }})
}],
},
{
path: 'ssg/:id',
component: SsgWithParams,
Expand Down Expand Up @@ -106,8 +113,10 @@ export default async function () {
'ssg/index.html': /ng-server-context="ssg".+ssg works!/,
'ssg/one/index.html': /ng-server-context="ssg".+ssg-with-params works!/,
'ssg/two/index.html': /ng-server-context="ssg".+ssg-with-params works!/,
// When static redirects as generated as meta tags.
// When static redirects are generated as meta tags.
'ssg-redirect/index.html': '<meta http-equiv="refresh" content="0; url=/ssg">',
'ssg-redirect-via-guard/index.html':
'<meta http-equiv="refresh" content="0; url=/ssg?foo=bar">',
};

for (const [filePath, fileMatch] of Object.entries(expects)) {
Expand Down