0

I'm trying to create isomorphic react app. This is my current code:

server.js

import express from 'express';
import React from 'react';
import { renderToString } from 'react-dom/server';
import { StaticRouter } from 'react-router-dom/server';
import dotenv from 'dotenv';
import mongoose from 'mongoose';
import App from './components/App';
import routes from '../routes/routes.js';
import path from 'path';

dotenv.config();

mongoose.connect(process.env.MONGODB_URI)
  .then(() => console.log('Connected to MongoDB'))
  .catch(err => console.error('Could not connect to MongoDB', err));

const app = express();

app.use(express.json());
app.use('', routes);
app.use(express.static(path.resolve(__dirname, 'public')));

app.get('/*', (req, res) => {
  const context = {};
  const appString = renderToString(
    <StaticRouter location={req.url} context={context}>
      <App />
    </StaticRouter>
  );

  const html = `
  <!DOCTYPE html>
  <html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Your App</title>
    <link rel="stylesheet" type="text/css" href="/styles.css">
  </head>
  <body>
    <div id="root">${appString}</div>
    <script src="/bundle.js"></script>
  </body>
  </html>
  `;

  res.send(html);
});



app.listen(3000, () => console.log('Server is running on port 3000'));

webpack.config.js

const path = require('path');
const nodeExternals = require('webpack-node-externals');

module.exports = [
  {
    // Client bundle configuration
    entry: './src/client.js',
    output: {
      path: path.resolve(__dirname, 'public'),
      filename: 'bundle.js',
    },
    module: {
      rules: [
        {
          test: /\.(js|jsx)$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env', '@babel/preset-react'],
            },
          },
        },
      ],
    },
    resolve: {
      extensions: ['.js', '.jsx'],
    },
    devServer: {
      publicPath: '/',
      contentBase: path.join(__dirname, 'public'),
      compress: true,
      port: 9000,
      hot: true,
    },
  },
  {
    // Server bundle configuration
    entry: './src/server.js',
    target: 'node',
    externals: [nodeExternals()],
    output: {
      path: path.resolve(__dirname, 'build'),
      filename: 'server.js',
    },
    module: {
      rules: [
        {
          test: /\.(js|jsx)$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env', '@babel/preset-react'],
            },
          },
        },
      ],
    },
    resolve: {
      extensions: ['.js', '.jsx'],
    },
  },
];

App.jsx

import React from 'react';
import {BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from './Home';
import Archive from './Archive';

const App = () => (
  <>
    <Router>
      <Routes>
        <Route path="/" element={ <Home /> }  />
        <Route path="/archive" element={ <Archive /> }  />
      </Routes>
    </Router>
  </>
);

export default App;

client.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';

if (typeof window !== 'undefined') {
  const root = document.getElementById('root');
  if (root) {
    ReactDOM.createRoot(root).render(<App />);
  }
}

After I run npm start I get Referrence Error: document is not defined. I think I understand the problem, but I cannot solve this. I've got also problem with rendering. I feel like there is a problem with my server.js app.get problem.

I tried with checking every import/export and tried with

typeof window !=='undefined'

but nothing works.

2
  • Does this help with your problem? stackoverflow.com/a/35068861/1832954 Commented May 23, 2024 at 13:00
  • Nope, i tried this already. Still same error. Commented May 23, 2024 at 13:43

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.