Skip to main content

Advanced Usage

Excluding / Including Keys

Use the excludeKeys() and includeKeys() operators from @ngrx-addons/common to control which parts of the state are persisted:

import { excludeKeys, includeKeys } from '@ngrx-addons/common';
import { PersistStateModule, localStorageStrategy } from '@ngrx-addons/persist-state';

PersistStateModule.forRoot<typeof reducers>({
states: [
{
key: 'counter',
storage: localStorageStrategy,
// Only persist specific keys
source: (state) => state.pipe(includeKeys(['count', 'name'])),
// Or exclude specific keys
// source: (state) => state.pipe(excludeKeys(['temporaryFlag'])),
},
],
});

Performance Optimization

By default, state is saved on every change (with a distinctUntilChanged check). For high-frequency updates, use debounceTime:

import { debounceTime } from 'rxjs/operators';
import { localStorageStrategy } from '@ngrx-addons/persist-state';

providePersistStore({
states: [
{
key: 'counter',
storage: localStorageStrategy,
source: (state) => state.pipe(debounceTime(1000)),
},
],
});

Multiple Storages for the Same Key

You can persist different parts of the same reducer key to different storages:

providePersistStore({
states: [
{
key: 'user',
storage: localStorageStrategy,
source: (state) => state.pipe(includeKeys(['preferences'])),
storageKey: 'user-prefs@store',
},
{
key: 'user',
storage: sessionStorageStrategy,
source: (state) => state.pipe(includeKeys(['session'])),
storageKey: 'user-session@store',
},
],
});

Initialization Strategies

Control when rehydration happens relative to app initialization:

BeforeAppInit (default)

State is rehydrated immediately, before APP_INITIALIZER completes. Your app starts with the persisted state already in the store.

AfterAppInit

State is rehydrated after APP_INITIALIZER completes. Useful when your initializers depend on the default state:

import { AfterAppInit } from '@ngrx-addons/common';

providePersistStore({
strategy: AfterAppInit,
states: [...],
});

When using AfterAppInit, call markAsInitialized() to trigger rehydration:

import { AfterAppInit } from '@ngrx-addons/common';

@Component({ ... })
export class AppComponent {
private readonly afterAppInit = inject(AfterAppInit);

ngOnInit() {
this.afterAppInit.markAsInitialized();
}
}

Server-Side Rendering (SSR)

The default runGuard checks typeof window !== 'undefined', which prevents persistence from running on the server. No additional configuration is needed for Angular Universal / SSR.

For testing, use noopStorage to disable persistence entirely:

import { noopStorage } from '@ngrx-addons/persist-state';

// In your test module
providePersistStore({
states: [{ key: 'counter', storage: noopStorage }],
});

Or provide a custom runGuard:

providePersistStore({
states: [
{
key: 'counter',
storage: localStorageStrategy,
runGuard: () => false, // Disable persistence
},
],
});