如何在使用Scully预渲染的Angular站点中实现指定HTML内容仅在浏览器运行时渲染
Alright, let's solve this problem where you want your guest-only navigation bar to stay hidden during Scully's pre-render process, and only show up when the Angular app runs in a user's browser. Here are two reliable methods to make this happen:
Method 1: Use Angular's Native Browser Detection
This approach leverages Angular's built-in tools to distinguish between the pre-render context (Scully) and a real browser environment.
- First, update your component to inject and use
PLATFORM_IDandisPlatformBrowser:
import { Component, Inject, PLATFORM_ID } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; @Component({ // Your existing component metadata (selector, templateUrl, etc.) }) export class YourComponent { isBrowser: boolean; isGuest = true; // Replace with your actual authentication logic constructor(@Inject(PLATFORM_ID) private platformId: Object) { // Check if we're running in a real browser this.isBrowser = isPlatformBrowser(this.platformId); } }
- Modify your HTML template to combine both the browser check and your existing
isGuestcondition:
<div class="nav" *ngIf="isBrowser && isGuest"> <a href="#" class="btn" routerLink="/create-user">Create User</a> <a href="#" class="btn" routerLink="/login">Login</a> </div>
During Scully's pre-render, isPlatformBrowser returns false, so this div won't be included in the static output. Once the app loads in a browser, Angular will evaluate both conditions and render the nav if isGuest is true.
Method 2: Use Scully's Built-in isBrowser Observable
Scully provides an observable that directly tells you if the app is running in a browser, which is perfect for this use case.
- Inject Scully's
ScullyRoutesServicein your component:
import { Component } from '@angular/core'; import { ScullyRoutesService } from '@scullyio/ng-lib'; import { map } from 'rxjs/operators'; @Component({ // Your existing component metadata }) export class YourComponent { isBrowser$ = this.scullyRoutes.isBrowser; isGuest = true; // Replace with your actual authentication logic constructor(private scullyRoutes: ScullyRoutesService) {} }
- Update the template to use the async pipe with the observable:
<div class="nav" *ngIf="(isBrowser$ | async) && isGuest"> <a href="#" class="btn" routerLink="/create-user">Create User</a> <a href="#" class="btn" routerLink="/login">Login</a> </div>
This works the same way as the first method: during pre-render, isBrowser$ emits false so the div is omitted. In the browser, it emits true, and Angular handles your isGuest check normally.
Key Reason This Works
Scully runs Angular in a server-like environment during pre-render, not a real browser. By adding a browser detection check to your *ngIf, you ensure the content is only processed and rendered when the app is running in a user's actual browser context.
内容的提问来源于stack exchange,提问作者socialsnobbish

