Skip to main content

Server-side Rendering

Prerequisites

An Angular project with server-side rendering enabled.

Overview

Apollo Orbit supports server-side rendering in two ways:

  1. It uses Angular's HttpClient under the hood which automatically supports server-side rendering as explained here.
  2. 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.

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());
}
})
]);
}