Server-side Rendering
Prerequisites
An Angular project with server-side rendering enabled.
Overview
Apollo Orbit supports server-side rendering in two ways:
- It uses Angular's
HttpClient
under the hood which automatically supports server-side rendering as explained here. - It uses Angular's
TransferState
to transfer Apollo Client's cache from server to client.
Setup
Setup SSR based on your angular project's style.
- Standalone
- Module
Update appConfig
app/app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideGraphQL } from './graphql/graphql.provider';
import { provideHttpClient, withFetch } from '@angular/common/http';
import { provideClientHydration, withHttpTransferCacheOptions } from '@angular/platform-browser';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideGraphQL()
provideHttpClient(withFetch()),
provideClientHydration(withHttpTransferCacheOptions({
includePostRequests: true
}))
]
};
Passing includePostRequests
to withHttpTransferCacheOptions
is required for default GraphQL setup where POST requests are used.
Update provideGraphQL
app/graphql/graphql.provider.ts
import { isPlatformBrowser } from '@angular/common';
import { EnvironmentProviders, PLATFORM_ID, TransferState, inject, makeEnvironmentProviders, makeStateKey, provideEnvironmentInitializer } from '@angular/core';
import { Apollo, InMemoryCache, provideApollo, withApolloOptions } from '@apollo-orbit/angular';
import { HttpLinkFactory, withHttpLink } from '@apollo-orbit/angular/http';
import { NormalizedCacheObject } from '@apollo/client';
const APOLLO_STATE_KEY = makeStateKey<NormalizedCacheObject>('APOLLO_STATE');
export function provideGraphQL(): EnvironmentProviders {
return makeEnvironmentProviders([
provideApollo(
withApolloOptions(() => {
const httpLinkFactory = inject(HttpLinkFactory);
const httpLink = httpLinkFactory.create({ uri: 'http://localhost:4000/graphql' });
const platformId = inject<object>(PLATFORM_ID);
const ssrOptions = isPlatformBrowser(platformId)
? { ssrForceFetchDelay: 200 }
: { ssrMode: true };
return {
link: httpLink,
cache: new InMemoryCache(),
...ssrOptions
};
}),
withHttpLink()
),
provideEnvironmentInitializer(() => {
const apollo = inject(Apollo);
const transferState = inject(TransferState);
const platformId = inject(PLATFORM_ID);
if (isPlatformBrowser(platformId)) {
const state = transferState.get(APOLLO_STATE_KEY, undefined);
apollo.cache.restore(state);
} else {
transferState.onSerialize(APOLLO_STATE_KEY, () => apollo.cache.extract());
}
})
]);
}
Update AppModule
app/app.module.ts
import { provideHttpClient, withFetch } from '@angular/common/http';
import { provideClientHydration, withHttpTransferCacheOptions } from '@angular/platform-browser';
@NgModule({
...
providers: [
provideHttpClient(withFetch()),
provideClientHydration(withHttpTransferCacheOptions({
includePostRequests: true
}))
]
})
export class AppModule { }
Passing includePostRequests
to withHttpTransferCacheOptions
is required for default GraphQL setup where POST requests are used.
Update GraphQLModule
app/graphql/graphql.module.ts
import { isPlatformBrowser } from '@angular/common';
import { Inject, NgModule, PLATFORM_ID, TransferState, inject, makeStateKey } from '@angular/core';
import { Apollo, InMemoryCache, provideApollo, withApolloOptions } from '@apollo-orbit/angular';
import { HttpLinkFactory, withHttpLink } from '@apollo-orbit/angular/http';
import { NormalizedCacheObject } from '@apollo/client';
const APOLLO_STATE_KEY = makeStateKey<NormalizedCacheObject>('APOLLO_STATE');
@NgModule({
providers: [
provideApollo(
withApolloOptions(() => {
const httpLinkFactory = inject(HttpLinkFactory);
const httpLink = httpLinkFactory.create({ uri: 'http://localhost:4000/graphql' });
const platformId = inject(PLATFORM_ID);
const ssrOptions = isPlatformBrowser(platformId)
? { ssrForceFetchDelay: 200 }
: { ssrMode: true };
return {
link: httpLink,
cache: new InMemoryCache(),
...ssrOptions
};
}),
withHttpLink()
)
]
})
export class GraphQLModule {
public constructor(
apollo: Apollo,
transferState: TransferState,
@Inject(PLATFORM_ID) platformId: { [key: string]: any }
) {
if (isPlatformBrowser(platformId)) {
const state = transferState.get(APOLLO_STATE_KEY, undefined);
apollo.cache.restore(state);
} else {
transferState.onSerialize(APOLLO_STATE_KEY, () => apollo.cache.extract());
}
}
}