Helmet right now is returning empty strings on server. I am not sure if the documentation explains it really well and the existing issues are rarely of any help !
Issue -
`console.log('title', helmet.title.toString());
console.log('meta', helmet.meta.toString());
console.log('link', helmet.link.toString());`
are all empty except title which logs <title data-react-helmet="true"></title>
A very similar problem exists here - react-helmet outputting empty strings on server-side
But it has ejected the app already for SSR. I haven't done so far and would wish not to only for react-helmet. Second, I need to dynamically call the meta tags from API and fill the same.
I am very unclear how these are working. How these pick up meta and links automatically underneath? Don't I need to set them?
I will eventually want to add custom meta tags for every route. But lets' get started for home page atleast for helmet
My implementation as per docs below:
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import { Provider } from 'react-redux';
import { ConnectedRouter } from 'react-router-redux';
import store from '../../src/store';
import {createMemoryHistory } from 'history';
import { ServerStyleSheet } from 'styled-components';
import Loadable from 'react-loadable';
import manifest from '../../build/asset-manifest.json';
import Helmet from 'react-helmet';
import App from '../../src/containers/app';
const path = require('path');
const fs = require('fs');
const history = createMemoryHistory({
initialEntries: ['/', '/next', '/last'],
initialIndex: 0
});
const modules = [];
const extractAssets = (assets, chunks) => Object.keys(assets)
.filter(asset => chunks.indexOf(asset.replace('.js', '')) > -1)
.map(k => assets[k]);
export default (req, res, next) => {
const filePath = path.resolve(__dirname, '..', '..', 'build', 'index.html');
fs.readFile(filePath, 'utf8', (err, htmlData) => {
if (err) {
console.error('err', err);
return res.status(404).end();
}
const sheet = new ServerStyleSheet();
const body = ReactDOMServer.renderToString(
sheet.collectStyles(<Provider store={store}>
<ConnectedRouter history={history}>
<Loadable.Capture report={m => modules.push(m)}>
<App />
</Loadable.Capture>
</ConnectedRouter>
</Provider>)
);
const helmet = Helmet.renderStatic();
console.log('title', helmet.title.toString());
console.log('meta', helmet.meta.toString());
console.log('link', helmet.link.toString());
const styleTags = sheet.getStyleTags();
const extraChunks = extractAssets(manifest, modules)
.map(c => `<script type="text/javascript" src="/${c}"></script>`);
return res.send(
htmlData.replace(
'<html>',
`<html ${helmet.htmlAttributes.toString()}>`
).replace(
'<head>',
`<head>
${helmet.title.toString()}
${helmet.meta.toString()}
${helmet.link.toString()}
</head>`
).replace(
'</head>',
`${styleTags}</head>`
).replace(
'<div id="root"></div>',
`<div id="root">${body}</div>`
).replace(
'<body>',
`<body ${helmet.bodyAttributes.toString()}>`
).replace(
'</body>',
extraChunks.join('') + '</body>'
)
);
});
};