Shahbaz Shoukat
Shahbaz Shoukat

Reputation: 21

Cannot Render Contentful content by using Angular Universal (SSR)

I am working on an angular app with Contentful CMS which needs to be SSR. I have followed all the steps mentioned here Angular Universal. But its just rendering the static content, not the dynamic content from Contentful. I have also tried TransferState API but its not working with Contentful. My code is

app.server.module.ts

import { NgModule } from '@angular/core';
import { ServerModule, ServerTransferStateModule } from '@angular/platform-server';

import { AppModule } from './app.module';
import { AppComponent } from './app.component';
import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader';

@NgModule({
  imports: [
    AppModule,
    ServerModule,
    ServerTransferStateModule,
    ModuleMapLoaderModule,
   ],
  bootstrap: [AppComponent],
})
export class AppServerModule {}

server.ts

import 'zone.js/dist/zone-node';

import * as express from 'express';
import {join} from 'path';

// Express server
const app = express();

const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist/browser');

// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const {AppServerModuleNgFactory, LAZY_MODULE_MAP, ngExpressEngine, provideModuleMap} =             
require('./dist/server/main');

const domino = require('domino');
const fs = require('fs');
const path = require('path');
const template = fs.readFileSync('./dist/browser/index.html').toString();
const win = domino.createWindow(template);
global['window'] = win;
global['document'] = win.document;

// Our Universal express-engine (found @                 
https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine('html', ngExpressEngine({
  bootstrap: AppServerModuleNgFactory,
  providers: [
    provideModuleMap(LAZY_MODULE_MAP)
  ]
}));

app.set('view engine', 'html');
app.set('views', DIST_FOLDER);

// Example Express Rest API endpoints
// app.get('/api/**', (req, res) => { });
// Serve static files from /browser
app.get('*.*', express.static(DIST_FOLDER, {
  maxAge: '1y'
}));

// All regular routes use the Universal engine
app.get('*', (req, res) => {
  res.render('index', { req });
});

// Start up the Node server
app.listen(PORT, () => {
  console.log(`Node Express server listening on http://localhost:${PORT}`);
});

contentful.service.ts

private client = createClient({
    space: ENV.contentful.spaceId,
    accessToken: ENV.contentful.token
  });

Am I doing something wrong or need something different for Contentful?

Thanks in advance.

Upvotes: 2

Views: 1302

Answers (2)

Shahbaz Shoukat
Shahbaz Shoukat

Reputation: 21

I have resolved the issue by using Contentful API instead its SDK. Use its API with HttpClient.

API Reference: https://www.contentful.com/developers/docs/references/content-delivery-api/

NOTE: Use full API url in HttpClient without any proxy.

Upvotes: 0

Kishan
Kishan

Reputation: 935

The Contentful SDK does not use Angular's HttpClient module to fetch data so the TransferState API won't work by default.

You first will need to use an adapter for axios as documented here: https://github.com/contentful/contentful.js/blob/master/ADVANCED.md#angular-universal

And then use TransferHttpCacheModule in your app.module.ts: https://github.com/angular/universal/blob/master/docs/transfer-http.md

Upvotes: 1

Related Questions