npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@neuralangular/angular-ssr

v0.2.0

Published

Angular-first SSR, hydration, route rules, cache policy and request context helpers for Neural Angular.

Readme

@neuralangular/angular-ssr

Angular-first SSR, hydration, route rules, cache policy, and request context helpers for Neural Angular.

This package is intentionally thin. It builds on Angular's official server rendering APIs instead of replacing them, then adds typed conventions for the repetitive pieces that production SSR apps usually need: hydration setup, route declarations, cache headers, host validation, request context, and test helpers.

Status

@neuralangular/angular-ssr is an early package. The current package version is 0.2.0, and the public surface is small and focused:

  • Client hydration helpers.
  • Server rendering provider composition.
  • Typed server route helpers.
  • Cache policy presets and header serialization.
  • Request context creation and DI.
  • Testing utilities for request and cache assertions.

The UI package does not depend on this package.

Version 0.2 adds request-scoped runtime configuration for serverless and multi-tenant deployments. Provider-specific deployment output remains outside this package in @neuralangular/angular-adapters.

Installation

pnpm add @neuralangular/angular-ssr

Peer dependencies:

  • @angular/common ^22.0.0
  • @angular/core ^22.0.0
  • @angular/platform-browser ^22.0.0
  • @angular/ssr ^22.0.0

The package declares Node >=22.12.0.

Entry Points

import {
  defineNeuralServerRoutes,
  neuralRoute,
  provideNeuralHydration,
  provideNeuralServerRuntime,
} from '@neuralangular/angular-ssr';

import {
  cachePolicyToHeaders,
  neuralCache,
  serializeCacheControl,
} from '@neuralangular/angular-ssr/cache';

import {
  createNeuralMockRequest,
  createNeuralMockRequestContext,
  expectSafePrivateCache,
} from '@neuralangular/angular-ssr/testing';

Inside this repository, Nx project names and TypeScript path aliases use @neural/angular-ssr. Published application code should use @neuralangular/angular-ssr.

Client Hydration

provideNeuralHydration wraps Angular's provideClientHydration and gives you a compact configuration for event replay, incremental hydration behavior, and HTTP Transfer Cache filtering.

import { provideNeuralHydration } from '@neuralangular/angular-ssr';

export const appConfig = {
  providers: [
    provideNeuralHydration({
      eventReplay: true,
      incremental: true,
      transferCache: {
        disabled: false,
        includeAuthenticatedRequests: false,
        includePostRequests: false,
        includeHeaders: ['cache-control', 'etag'],
      },
    }),
  ],
};

Defaults are conservative:

  • Event replay is enabled only when eventReplay: true is passed.
  • Incremental hydration remains enabled unless incremental: false is passed.
  • Authenticated requests are not included in Transfer Cache unless explicitly enabled.
  • Transfer Cache headers are sanitized to a small allowlist and sensitive headers are denylisted.

Server Rendering

Use Angular's official provideServerRendering(withRoutes(serverRoutes)) directly, then add Neural runtime providers next to it. Keeping withRoutes() visible lets Angular's hybrid build discover routes correctly.

import { provideServerRendering, withRoutes } from '@angular/ssr';
import { provideNeuralServerRuntime } from '@neuralangular/angular-ssr';
import { serverRoutes } from './app.routes.server';

export const serverConfig = {
  providers: [
    provideServerRendering(withRoutes(serverRoutes)),
    provideNeuralServerRuntime({
      allowedHosts: ['example.com'],
      trustProxyHeaders: false,
      canonicalOrigin: 'https://example.com',
    }),
  ],
};

For serverless environments, pass a factory. It runs independently for every Angular render request:

provideNeuralServerRuntime((request) => ({
  allowedHosts: [new URL(request.url).host],
  canonicalOrigin: process.env['NEURAL_CANONICAL_ORIGIN'],
}));

For Vercel Build Output API generation and Node Function helpers, install @neuralangular/angular-adapters and import its /vercel entry point.

provideNeuralServerRendering({ routes }) remains available for compatibility with 0.0.1, but it is deprecated. New applications should not use it.

Server Routes

defineNeuralServerRoutes and neuralRoute create Angular ServerRoute objects with cache/header helpers and validation.

import {
  defineNeuralServerRoutes,
  neuralRoute,
} from '@neuralangular/angular-ssr';

export const serverRoutes = defineNeuralServerRoutes([
  neuralRoute.prerender(''),

  neuralRoute.server('products/:id', {
    cache: 'public-swr',
    headers: {
      'X-App-Route': 'product-detail',
    },
  }),

  neuralRoute.client('dashboard/**', {
    cache: 'private-no-store',
  }),

  neuralRoute.prerender('blog/:slug', {
    fallback: 'server',
    getPrerenderParams: async () => [
      { slug: 'getting-started' },
      { slug: 'theme-tokens' },
    ],
  }),
]);

Route validation currently catches:

  • Leading slash compatibility. /products/:id and products/:id produce the same Angular route path.
  • Duplicate routes with the same path and render mode.
  • Invalid wildcard patterns. A wildcard must be exactly ** or end with /**.
  • Absolute URLs, query strings, fragments, double slashes, and control characters.
  • Prerender routes that try to define an HTTP status.
  • Prerender fallback usage without getPrerenderParams.

Cache Policies

The cache entry point exposes reusable presets and conversion helpers.

import {
  cachePolicyToHeaders,
  neuralCache,
} from '@neuralangular/angular-ssr/cache';

const swrHeaders = cachePolicyToHeaders('public-swr');

const privateHeaders = neuralCache.withHeaders({
  visibility: 'private',
  noStore: true,
});

Built-in presets:

| Preset | Intended use | | -------------------- | ------------------------------------------------------------------ | | public-static | Mostly static public pages. | | public-short | Public dynamic content that can be cached briefly. | | public-swr | Public SSR content that should respond quickly while revalidating. | | private-revalidate | Private user content that must revalidate. | | private-no-store | Sensitive private data that should not be cached. | | immutable-asset | Fingerprinted static assets. |

immutable-asset is retained in the shared preset union for compatibility, but it is intended for versioned assets, not HTML routes. Page route examples should use public-static, public-short, public-swr, private-revalidate, or private-no-store.

The lower-level API is also available:

import { serializeCacheControl } from '@neuralangular/angular-ssr/cache';

const header = serializeCacheControl({
  visibility: 'public',
  maxAge: 60,
  sharedMaxAge: 300,
  staleWhileRevalidate: 900,
});

Contradictory policies fail early, including public no-store, private s-maxage, positive max-age with no-store, must-revalidate with immutable, and public Vary: Cookie without explicit opt-in.

ETag helpers are deterministic and body-based:

import { createNeuralEtag } from '@neuralangular/angular-ssr/cache';

const etag = await createNeuralEtag(html, {
  strength: 'weak',
});

cachePolicyToHeaders() serializes provided etag and lastModified values, but it does not invent them. Last-Modified should come from real resource metadata.

Request Context

Request context utilities turn a Fetch Request into an Angular-injectable value.

import {
  NEURAL_REQUEST_CONTEXT,
  createNeuralRequestContext,
  injectNeuralRequestContext,
  injectRequiredNeuralRequestContext,
  provideNeuralRequestContext,
} from '@neuralangular/angular-ssr';

const context = createNeuralRequestContext({
  request,
  allowedHosts: ['example.com'],
  canonicalOrigin: 'https://example.com',
  trustProxyHeaders: true,
});

export const requestProviders = [provideNeuralRequestContext(context)];

In universal code, use the nullable helper:

import { injectNeuralRequestContext } from '@neuralangular/angular-ssr';

const requestContext = injectNeuralRequestContext();

In server-only code, use the required helper:

import { injectRequiredNeuralRequestContext } from '@neuralangular/angular-ssr';

const requestContext = injectRequiredNeuralRequestContext();

The context includes id, url, origin, host, protocol, optional locale, and trustedProxy. In the browser, NEURAL_REQUEST_CONTEXT resolves to null.

Proxy headers are ignored by default. Set trustProxyHeaders only behind a trusted proxy, preferably with an explicit header policy.

Transfer Cache Safety

Transfer Cache header inclusion is allowlisted and denylisted. These headers can never be transferred, regardless of configuration:

  • authorization
  • proxy-authorization
  • cookie
  • set-cookie
  • x-api-key
  • x-auth-token

Requests with credentials or auth-like request headers are excluded unless authenticated requests are explicitly enabled.

Migration From 0.0.1

Replace this deprecated pattern:

provideNeuralServerRendering({
  routes: serverRoutes,
});

with:

provideServerRendering(withRoutes(serverRoutes));
provideNeuralServerRuntime({
  allowedHosts: ['example.com'],
  trustProxyHeaders: false,
  canonicalOrigin: 'https://example.com',
});

Also prefer route paths without a leading slash. Leading slash input remains supported for compatibility.

Testing

The testing entry point provides small helpers for package and app tests:

import {
  createNeuralMockRequest,
  createNeuralMockRequestContext,
  expectSafePrivateCache,
} from '@neuralangular/angular-ssr/testing';

const request = createNeuralMockRequest('https://example.test/dashboard');
const context = createNeuralMockRequestContext(
  'https://example.test/dashboard',
);

expectSafePrivateCache({
  visibility: 'private',
  noStore: true,
});

Workspace Commands

From the repository root:

pnpm nx run @neural/angular-ssr:build
pnpm nx run @neural/angular-ssr:typecheck
pnpm nx run @neural/angular-ssr:test
pnpm nx run @neural/angular-ssr:lint
pnpm nx run @neural/angular-ssr:api-check
pnpm nx run @neural/angular-ssr:external-check
pnpm nx run angular-ssr:build
pnpm nx run angular-ssr:e2e

Design Notes

  • The package should stay Angular-native and avoid replacing Angular SSR.
  • Browser-only work belongs behind Angular platform checks or client-only lifecycle boundaries.
  • Cache helpers should serialize predictable HTTP headers and fail early on unsafe combinations.
  • UI must remain independent from SSR.
  • Future meta-framework features should build on this package, not be required by it.