Skip to content
Merged
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
30 changes: 13 additions & 17 deletions packages/angular/ssr/src/utils/ng.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.dev/license
*/

import { APP_BASE_HREF, PlatformLocation } from '@angular/common';
import { LocationStrategy } from '@angular/common';
import {
ApplicationRef,
type PlatformRef,
Expand All @@ -21,7 +21,7 @@ import {
platformServer,
ɵrenderInternal as renderInternal,
} from '@angular/platform-server';
import { ActivatedRoute, Router } from '@angular/router';
import { ActivatedRoute, Router, UrlSerializer } from '@angular/router';
import { Console } from '../console';
import { joinUrlParts, stripIndexHtmlFromURL } from './url';

Expand Down Expand Up @@ -60,12 +60,12 @@ export async function renderAngular(
serverContext: string,
): Promise<{ hasNavigationError: boolean; redirectTo?: string; content: () => Promise<string> }> {
// A request to `http://www.example.com/page/index.html` will render the Angular route corresponding to `http://www.example.com/page`.
const urlToRender = stripIndexHtmlFromURL(url).toString();
const urlToRender = stripIndexHtmlFromURL(url);
const platformRef = platformServer([
{
provide: INITIAL_CONFIG,
useValue: {
url: urlToRender,
url: urlToRender.href,
document: html,
},
},
Expand Down Expand Up @@ -96,31 +96,27 @@ export async function renderAngular(
applicationRef = await bootstrap({ platformRef });
}

const envInjector = applicationRef.injector;
const router = envInjector.get(Router);
const initialUrl = router.currentNavigation()?.initialUrl.toString();

// Block until application is stable.
await applicationRef.whenStable();

// TODO(alanagius): Find a way to avoid rendering here especially for redirects as any output will be discarded.
const envInjector = applicationRef.injector;
const routerIsProvided = !!envInjector.get(ActivatedRoute, null);
const router = envInjector.get(Router);
const lastSuccessfulNavigation = router.lastSuccessfulNavigation();

if (!routerIsProvided) {
hasNavigationError = false;
} else if (lastSuccessfulNavigation?.finalUrl && initialUrl !== null) {
} else if (lastSuccessfulNavigation?.finalUrl) {
hasNavigationError = false;

const { finalUrl } = lastSuccessfulNavigation;
const finalUrlStringified = finalUrl.toString();

if (initialUrl !== finalUrlStringified) {
const baseHref =
envInjector.get(APP_BASE_HREF, null, { optional: true }) ??
envInjector.get(PlatformLocation).getBaseHrefFromDOM();
const urlSerializer = envInjector.get(UrlSerializer);
const locationStrategy = envInjector.get(LocationStrategy);
const finalUrlSerialized = urlSerializer.serialize(lastSuccessfulNavigation.finalUrl);
const finalExternalUrl = joinUrlParts(locationStrategy.getBaseHref(), finalUrlSerialized);

redirectTo = joinUrlParts(baseHref, finalUrlStringified);
if (urlToRender.href !== new URL(finalExternalUrl, urlToRender.origin).href) {
redirectTo = finalExternalUrl;
}
}

Expand Down