1. Concepts

Loaders cache layer and tags revalidation

Version: 1.x

Loaders have a caching layer that stores their execution results, including page and dictionary data. The Angular Content SDK uses the unstorage module for underlying cache semantics. It operates on the stale-while-revalidate principle to minimize requests to the SitecoreAI Edge endpoint and optimize front-end performance.

Cache initialization

Caching is initialized in the src/server.ts file and passed into the Angular SSR layer:

import memoryDriver from 'unstorage/drivers/memory';

const driver = memoryDriver();

const loaderCache = createLoaderCache({
  revalidate: config.angular.loadersCache.revalidate,
  enabled: config.angular.loadersCache.enabled,
  defaultSiteName: config.defaultSite,
  driver,
});

// ...

app.use((req, res, next) => {
  angularApp
    .handle(req, { cache: loaderCache })
    .then((response) =>
      response ? writeResponseToNodeResponse(response, res) : next()
    )
    .catch((err) => {
      next(err);
    });
});

By default, caching is enabled and uses the unstorage memory driver, which stores data in runtime system memory.

Note

The memory driver is not optimal for production deployments in serverless environments such as Vercel or Netlify. For these scenarios, import and use a custom unstorage driver. For the full list of supported drivers, refer to the unstorage drivers documentation.

Cache configuration

You can configure caching and revalidation at three levels:

  • Global
  • Per-loader
  • Per-route

Global configuration

Global cache settings are available in sitecore.config.ts under the angular.loadersCache section:

export default defineConfig({
  angular: {
    loadersCache: {
      // Enable or disable caching
      enabled: true,
      // Time in seconds until a cache entry becomes stale
      revalidate: 300,
    },
  },
  // ...
});

Per-loader configuration

You can pass cache options to individual loaderResolver calls in app.routes.ts. The following example disables caching for all page loader executions across all routes:

{
  path: '**',
  component: PageComponent,
  resolve: {
    page: loaderResolver('page', { enabled: false }),
    dictionary: loaderResolver('dictionary'),
  },
}

Per-route configuration

You can also configure loaders differently for specific routes:

{
  path: '/fully-dynamic-page',
  component: PageComponent,
  resolve: {
    page: loaderResolver('page', { enabled: false }),
    dictionary: loaderResolver('dictionary'),
  },
},
{
  path: '/cached-once-page',
  component: PageComponent,
  resolve: {
    page: loaderResolver('page', { enabled: true, revalidate: 0 }),
    dictionary: loaderResolver('dictionary', { revalidate: 3000 }),
  },
},
{
  path: '**',
  component: PageComponent,
  resolve: {
    page: loaderResolver('page'),
    dictionary: loaderResolver('dictionary'),
  },
}

Per-route cache options reference

The PerRouteLoaderCacheConfig interface describes all available per-route caching options:

Property

Type

Description

revalidate

number

Time-to-live (TTL) in seconds. A positive value N, expires the entry after N seconds. Setting to 0 or a negative value means the entry never expires.

enabled

boolean

When false, every call bypasses the cache and falls through to the loader directly.

tags

string[]

Custom tags applied to every entry the loader writes. This is merged with built-in tags (sc:site, sc:locale, sc:locale for page loaders).

Cache tags and revalidation

Every cache entry is automatically tagged with contextual metadata:

  • For dictionary and page loader data - locale
  • For page loader data only - item ID, variant ID, route, and other request data

You can also apply custom tags via the tags option in your cache configuration.

The revalidate endpoint

The Content SDK exposes a /api/revalidate endpoint that enables conditional revalidation of cache entries by tag. This allows partial cache invalidation to be triggered via webhooks (for example, from Sitecore Edge).

Configure the revalidation middleware in src/server.ts. It must receive the same cache instance passed to the Angular SSR layer:

/** Production webhook: POST /api/revalidate (Sitecore Edge OSR). */
app.use(
  createSitecoreRevalidateMiddleware({
    cache: loaderCache,
    defaultLocale: config.defaultLanguage,
    sites: [/* ... */],
  })
);
If you have suggestions for improving this article, let us know!