Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SSR with React : Unexpected token '<' in call to renderToString()

I'm working on SSR with react but I'm encountering the following error.
Syntax error: Unexpected token '<'`

 <div id="root">${ReactDOMServer.renderToString(<App />)}</div>```
                                                ^

As mentioned is here

babel-register doesn't process the file it is called from.

Therefore, I rightly declared my babel dependencies in a new file, however I'm still getting the above error.

Below is my index.js file

import babelRegister from '@babel/register';
import ignoreStyles from 'ignore-styles';

babelRegister({
  ignore: [/node_modules/],
  presets: ['@babel/preset-env', '@babel/preset-react'],
});

import express from 'express';
import appRender from './server.js';

const app = express();
appRender(app);

My server.js file.

import initialRenderRoutes from './routes/initialRenderRoutes.js';
import path from 'path';

const appRender = (app) => {
  const __dirname = path.resolve();

  app.use(express.static(path.resolve(__dirname, '../build')));

  app.use('*', initialRenderRoutes);

  const port = 5000;

  app.listen(port, () => console.log(`Server running on port ${port}`));
};
export default appRender;

My initialController.js file

import fs from 'fs';
import ReactDOMServer from 'react-dom/server.js';
import path from 'path';

import App from '../../src/App.js';

const initialRenderController = (req, res, next) => {
  console.log(path.resolve());
  fs.readFile(
    path.resolve('../client/build/index.html'),
    'utf8',
    (err, data) => {
      if (err) {
        console.log(err);
        return res.status(500).send('Internal Server Error');
      }
      return res.send(
        data.replace(
          '<div id="root"></div>',
          `<div id="root">${ReactDOMServer.renderToString(<App />)}</div>`
              <<<<The problem lies here>>>>
        )
      );
    }
  );
};

export default initialRenderController;

Is it something related to babel, please help.

like image 717
Tarun Singh Avatar asked Nov 23 '25 19:11

Tarun Singh


1 Answers

Try the below changes in your index.js file,

require('ignore-styles');

require('@babel/register')({
    ignore: [/(node_modules)/],
    presets: ['@babel/preset-env', '@babel/preset-react']
});

require('./server');
require('./initialController');

The above should work, I tested locally the below, it works perfectly fine.

My server.js

import express from 'express';
import fs from 'fs';
import path from 'path';

import React from 'react';
import ReactDOMServer from 'react-dom/server';

import App from '../App';

const app = express();

app.use('^/$', (req, res, next) => {

    fs.readFile(path.resolve('./build/index.html'), 'utf-8', (err, data) => {
        if (err) {
            console.log(err);
            return res.status(500).send("Some error occurred")
        }
        return res.send(data.replace('<div id="root"></div>', `<div id="root">${ReactDOMServer.renderToString(<App />)}</div>`))
    })
});

app.use(express.static(path.resolve(__dirname, "..", "build")));

app.listen(5000, ()=>{
    console.log("App running on port 5k")
})

index.js

require('ignore-styles');

require('@babel/register')({
    ignore: [/(node_modules)/],
    presets: ['@babel/preset-env', '@babel/preset-react']
});

require('./server');

I hope you have the .babelrc file with the required presets.

Update in response to comment:

Consider removing type: "module", since it will throw error when you use require. @babel/register will run files using babel on the fly. The require hook will bind itself to the node’s require and will automatically compile files at runtime. server.js using es module won't clash if you remove type: "module". The order of require matters, we require babel-register in index.js with the presets needed to recognize the syntaxes in the then-required server.js.

like image 94
deechris27 Avatar answered Nov 25 '25 09:11

deechris27