Community编程与开发github.com

analogjs/angular-ssr

使用 @angular/ssr 在 Angular v20+ 中实现服务端渲染和水合。用于 SSR 设置、水合策略、静态页面预渲染以及处理仅浏览器 API。触发条件包括 SSR 配置、修复水合不匹配、预渲染路由或使代码兼容 SSR。

angular-ssr 是什么?

该技能专注于在 Angular v20 及以上版本中利用 `@angular/ssr` 包实现服务端渲染(SSR)和水合功能。它引导开发者完成 SSR 设置和配置,包括启用水合(`provideClientHydration()`)、处理水合不匹配以及实现预渲染策略。该技能还涵盖处理 `window`、`document` 等浏览器独有 API 的最佳实践,并确保代码在服务端和客户端环境中都能正确运行。它支持多种平台,如 Cursor 和 Claude Code,并基于 SKILL.md 文档中的官方指南提供逐步说明。对于构建生产级 Angular 应用、优化首屏加载时间和 SEO 的开发者来说,此技能至关重要。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/analogjs/angular-skills/tree/main/skills/angular-ssr

Installed? Explore more 编程与开发 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

angular-ssr 是做什么的?

使用 @angular/ssr 在 Angular v20+ 中实现服务端渲染和水合。用于 SSR 设置、水合策略、静态页面预渲染以及处理仅浏览器 API。触发条件包括 SSR 配置、修复水合不匹配、预渲染路由或使代码兼容 SSR。

要求

  • Angular v20+(推荐 v21+)
  • @angular/ssr 包(在 angular.json 中配置 server builder 时默认包含)

设置 SSR

  1. 将 SSR 功能添加到一个新的 Angular 工作区:

    ng new my-app --ssr
    
  2. 或者,将 SSR 添加到一个现有的应用:

    ng add @angular/ssr
    

水合

SSR 默认启用 provideClientHydration(),但您可以通过从 @angular/platform-browser 导入并调用 provideClientHydration() 来明确启用它。

在您的 app.config.ts 中:

import { ApplicationConfig } from '@angular/core';
import { provideClientHydration } from '@angular/platform-browser';

export const appConfig: ApplicationConfig = {
  providers: [provideClientHydration()]
};

水合不匹配

水合不匹配会导致控制台错误。常见原因包括:

  • 动态内容:使用服务器和客户端不同步的日期、随机数。使用 ngSkipHydration 跳过元素的水合。
  • 不可预见的 DOM 结构:避免在 SSR 期间修改 DOM。
  • 第三方脚本:确保第三方库在 SSR 期间不操作 DOM。

修复不匹配的步骤:

  1. 检查浏览器控制台中类似 Hydration node mismatch 的错误。
  2. 使用 provideClientHydration() 的 withDomEventsReplay() 事件重播。
  3. 作为临时措施,将 ngSkipHydration 属性添加到有问题的元素上。

预渲染

要预渲染静态路由(通常是主页),请配置 angular.json 中的 prerender 选项:

"architect": {
  "build": {
    "builder": "@angular-devkit/build-angular:application",
    "options": {
      "prerender": {
        "routes": [
          "/",
          "/about",
          "/contact"
        ]
      }
    }
  }
}

使代码兼容 SSR

  • 避免在服务端使用 window、document、localStorage。
  • 使用 Angular 的 isPlatformBrowser() 和 isPlatformServer() 函数守卫浏览器特定代码。
import { isPlatformBrowser, isPlatformServer } from '@angular/common';

constructor(@Inject(PLATFORM_ID) private platformId: Object) {
  if (isPlatformBrowser(this.platformId)) {
    // 浏览器特定的代码
    console.log('在浏览器中运行');
  }
}
  • 或者,使用 afterNextRender 或 afterRender 来延迟浏览器特定的逻辑:
import { afterNextRender } from '@angular/core';

constructor() {
  afterNextRender(() => {
    // 此代码仅在浏览器中运行
  });
}

测试

在 app.component.spec.ts 中,导入 provideClientHydration() 以确保测试环境支持 SSR:

import { provideClientHydration } from '@angular/platform-browser';

beforeEach(async () => {
  await TestBed.configureTestingModule({
    providers: [provideClientHydration()]
  }).compileComponents();
});

故障排除

  • 错误:ERROR TypeError: Cannot read properties of null (reading '...') -- 通常由水合不匹配引起。检查 DOM 差异。
  • 错误:ReferenceError: window is not defined -- 服务端代码中使用了浏览器 API。使用 isPlatformBrowser() 守卫或 afterNextRender。
  • 性能问题:考虑使用 withDomEventsReplay() 来减少水合期间的事件处理开销。

Individual skills in this repo

This repo contains 9 individual skills — each has its own dedicated page.

analogjs/angular-component

Create modern Angular standalone components following v20+ best practices. Use for building UI components with signal-based inputs/outputs, OnPush change detection, host bindings, content projection, and lifecycle hooks. Triggers on component creation, refactoring class-based inputs to signals, adding host bindings, or implementing accessible interactive components.

analogjs/angular-di

Implement dependency injection in Angular v20+ using inject(), injection tokens, and provider configuration. Use for service architecture, providing dependencies at different levels, creating injectable tokens, and managing singleton vs scoped services. Triggers on service creation, configuring providers, using injection tokens, or understanding DI hierarchy.

analogjs/angular-directives

Create custom directives in Angular v20+ for DOM manipulation and behavior extension. Use for attribute directives that modify element behavior/appearance, structural directives for portals/overlays, and host directives for composition. Triggers on creating reusable DOM behaviors, extending element functionality, or composing behaviors across components. Note - use native @if/@for/@switch for control flow, not custom structural directives.

analogjs/angular-forms

Build signal-based forms in Angular v21+ using the new Signal Forms API. Use for form creation with automatic two-way binding, schema-based validation, field state management, and dynamic forms. Triggers on form implementation, adding validation, creating multi-step forms, or building forms with conditional fields. Signal Forms are experimental but recommended for new Angular projects. Don't use for template-driven forms without signals or third-party form libraries like Formly or ngx-formly.

analogjs/angular-http

Implement HTTP data fetching in Angular v20+ using resource(), httpResource(), and HttpClient. Use for API calls, data loading with signals, request/response handling, and interceptors. Triggers on data fetching, API integration, loading states, error handling, or converting Observable-based HTTP to signal-based patterns.

analogjs/angular-routing

Implement routing in Angular v20+ applications with lazy loading, functional guards, resolvers, and route parameters. Use for navigation setup, protected routes, route-based data loading, and nested routing. Triggers on route configuration, adding authentication guards, implementing lazy loading, or reading route parameters with signals.

analogjs/angular-signals

Implement signal-based reactive state management in Angular v20+. Use for creating reactive state with signal(), derived state with computed(), dependent state with linkedSignal(), and side effects with effect(). Triggers on state management questions, converting from BehaviorSubject/Observable patterns to signals, or implementing reactive data flows.

analogjs/angular-testing

Write unit and integration tests for Angular v20+ applications using Vitest or Jasmine with TestBed and modern testing patterns. Use for testing components with signals, OnPush change detection, services with inject(), and HTTP interactions. Triggers on test creation, testing signal-based components, mocking dependencies, or setting up test infrastructure. Don't use for E2E testing with Cypress or Playwright, or for testing non-Angular JavaScript/TypeScript code.

analogjs/angular-tooling

Use Angular CLI and development tools effectively in Angular v20+ projects. Use for project setup, code generation, building, testing, and configuration. Triggers on creating new projects, generating components/services/modules, configuring builds, running tests, or optimizing production builds. Don't use for Nx workspace commands, custom Webpack configurations, or non-Angular CLI build systems like Vite standalone or esbuild direct usage.

相关技能