react-helmet mixing fields during renderStatic

react-helmet mixing fields during renderStatic

I'm running server-side render of the React application. I'm using&nbsp;<code>express</code>&nbsp;for this purposes. The whole server-side render code looks like this:

I'm running server-side render of the React application. I'm using express for this purposes. The whole server-side render code looks like this:

import * as React from "react"
import * as ReactDOMServer from "react-dom/server"
import * as express from "express"
import { StaticRouter } from "react-router-dom"
import walker = require("react-tree-walker")
import { useStaticRendering } from "mobx-react"

import Helmet from "react-helmet" import Provider from "../src/Provider" import { StaticRouterContext } from "react-router"

import version = require("../version")

interface IRenderResponse { statusCode: number, template: string, redirect?: string }

const run = (url: string, locale?: string): Promise<IRenderResponse> => { var template: string = require(../dist/${version.v()}/index.html) var html: string = "" var head: object var context: StaticRouterContext = {}

useStaticRendering(true)

var routing = (
    &lt;StaticRouter 
        location={url} 
        context={context}
    &gt;
        &lt;Provider defaultLocale={locale} /&gt;
    &lt;/StaticRouter&gt;
)

return new Promise((resolve) =&gt; {
    walker(routing, (element, instance) =&gt; {
        if (instance &amp;&amp; typeof instance._prepare == typeof (() =&gt; {}))
            return instance._prepare()
    }).then(() =&gt; {
        html = ReactDOMServer.renderToString(routing)
        head = Helmet.renderStatic()
        template = template.replace(/\${__rh-([a-z]+)}/gi, (match, group) =&gt; {
            return head[group].toString()
        })
        template = template.replace(/\${__body}/gi, (match) =&gt; {
            return html
        })
        if (context.url)
            context["statusCode"] = 301

        resolve({
            statusCode: context["statusCode"] || 200, 
            template, 
            redirect: context.url
        })
    }).catch((error) =&gt; {
        template = template.replace(/\${__rh-([a-z]+)}/gi, "")
        template = template.replace(/\${__body}/gi, error.stack || error.toString())
        resolve({
            statusCode: 500, 
            template
        })
    })
})

}

var app = express()

app.get("*", (req, res) => { var accepted = req.acceptsLanguages() var locale = accepted ? (accepted[0] || "ru").split("-")[0] : "ru" run(req.originalUrl, locale).then((data) => { if (data.redirect) res.redirect(data.redirect) else res.status(data.statusCode).send(data.template) }) })

app.listen(1239)

You can see that the react-tree-walker is used here. But this problem occurs whatever I'm using for the server-side render.

The problem is that if my node-js server is running in one thread, the if two different requests are being done simultaneously, then react-helmet mixes fields. For example, if there are two views:

class FirstView extends React.Component {
    render() {
        return (
            <Helmet>
                <title>This is first title</title>
                <meta name="description" content="My first view description" />
            </Helmet>
        )
    }
}

and

class SecondView extends React.Component {
    render() {
        return (
            <Helmet>
                <title>This is second title</title>
                <meta name="description" content="My second view description" />
            </Helmet>
        )
    }
}

then I can receive the head something like that:

<title>This is first title</title>
<meta name="description" content="My second view description" />

Obviously this happens because of react-helmet uses static fields, I suppose. So, if two request are being handled in parallel, this fields are being changed chaoticaly.

How can I defeat it? This problem often occurs for high-load projects, and this can crash the SEO, because crawler can receive wrong data.

webpack.config.js:

var webpack = require("webpack")

var config = { mode: "production", target: "node", entry: dirname + "/index.tsx", output: { path: __dirname, filename: index.js }, module: { rules: [ { test: require.resolve("phoenix"), use: "imports-loader?window=>global" }, { test: /.tsx?$/, loader: "awesome-typescript-loader?configFileName=tsconfig.server.json", exclude: /node_modules/ }, { test: /.js$/, enforce: "pre", loader: "source-map-loader" }, { test: /.html$/, loader: "html-loader" }, { test: /.(svg|woff|woff2|ttf|otf|png|jpg)$/, loader: "url-loader" }, { test: /.(css|sass)$/, loader: "ignore-loader" } ] }, resolve: { modules: [ "node_modules", `${dirname}/../src` ], extensions: [".js", ".jsx", ".sass", ".json", ".css", ".ts", ".tsx"] }, parallelism: 2, plugins: [ new webpack.DefinePlugin({ "ENV": JSON.stringify("server"), "process.env.ENV": JSON.stringify("server"), "process.env.VERSION": JSON.stringify("n/a"), "process.env.NODE_ENV": JSON.stringify("production"), "global.GENTLY": false }) ] }

module.exports = config


Angular 9 Tutorial: Learn to Build a CRUD Angular App Quickly

What's new in Bootstrap 5 and when Bootstrap 5 release date?

Brave, Chrome, Firefox, Opera or Edge: Which is Better and Faster?

How to Build Progressive Web Apps (PWA) using Angular 9

What is new features in Javascript ES2020 ECMAScript 2020

How to Use Express.js, Node.js and MongoDB.js

In this post, I will show you how to use Express.js, Node.js and MongoDB.js. We will be creating a very simple Node application, that will allow users to input data that they want to store in a MongoDB database. It will also show all items that have been entered into the database.

Node.js for Beginners - Learn Node.js from Scratch (Step by Step)

Node.js for Beginners - Learn Node.js from Scratch (Step by Step) - Learn the basics of Node.js. This Node.js tutorial will guide you step by step so that you will learn basics and theory of every part. Learn to use Node.js like a professional. You’ll learn: Basic Of Node, Modules, NPM In Node, Event, Email, Uploading File, Advance Of Node.

Top 7 Most Popular Node.js Frameworks You Should Know

Node.js is an open-source, cross-platform, runtime environment that allows developers to run JavaScript outside of a browser. In this post, you'll see top 7 of the most popular Node frameworks at this point in time (ranked from high to low by GitHub stars).