I will try my best to explain my situation. I created a component called MetaDecorator.js
which has the helmet and following config:
import React from 'react'
import PropTypes from 'prop-types'
import { Helmet } from 'react-helmet'
const MetaDecorator = ({ title, description, keywords }) => {
return (
<Helmet>
<title>My Website - Discover Great Resorts | {title} </title>
<meta name="description" content={description} />
<meta name="keywords" content={keywords} />
</Helmet>
)
}
MetaDecorator.propTypes = {
title: PropTypes.string.isRequired,
description: PropTypes.string.isRequired,
keyword: PropTypes.string.isRequired
}
export default MetaDecorator
Next, I added this to each of my screen pages for instance on HomeScreen.js
, I used it like this:
import MetaDecorator from '../components/MetaDecorator'
import homeMeta from '../data/home'
const HomeScreen = () => {
return (
<>
<MetaDecorator
title={homeMeta.pageTitle}
description={homeMeta.pageDescription}
keywords={homeMeta.pageKeyword}
/>
For each pages I've added this MetaDecorator and setting up the props to my helmet. Now on my backend folder under server.js
I've added the following codes:
import path from 'path'
import express from 'express'
import dotenv from 'dotenv'
import colors from 'colors'
import morgan from 'morgan'
import { notFound, errorHandler } from './middleware/errorMiddleware.js'
import connectDB from './config/db.js'
import React from 'react'
import App from './src/App'
import { renderToString } from 'react-dom/server'
dotenv.config()
connectDB()
const app = express()
if(process.env.NODE_ENV === 'development'){
app.use(morgan('dev'))
}
app.get('/', (req, res) => {
res.send('API is running...')
const app = renderToString(<App />);
const helmet = Helmet.renderStatic();
res.send(formatHTML(app, helmet));
})
function formatHTML(appStr, helmet) {
return `
<!DOCTYPE html>
<html lang="en">
<head>
${helmet.title.toString()}
${helmet.meta.toString()}
</head>
<body>
<div id="root">
${ appStr }
</div>
<script src="./bundle.js"></script>
</body>
</html>
`
}
app.listen(PORT, console.log(`Server running in ${MODE} mode on port ${PORT})
When I run the app its complaining about this:
file:///C:/Users/Robert/Desktop/MERN/mywebsite/backend/server.js:31
[0] const app = renderToString(<MetaDecorator />);
My folder client and backend are inside the same folder as I did not separate them. My question is am I doing this right? How should I fix my error? Is there a better way to do this?
Please help I am a beginner here.
UPDATE: Here's my package.json file on the root:
{
"name": "iko-app",
"version": "1.0.0",
"description": "",
"main": "server.js",
"type": "module",
"scripts": {
"start": "node backend/server",
"server": "nodemon backend/server",
"client": "npm start --prefix frontend",
"dev": "concurrently "npm run server" "npm run client"",
"data:import": "node backend/seeder",
"data:destroy": "node backend/seeder -destroy"
},
"repository": {
"type": "git",
"url": "git+https://github.com/mywebsite.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/mywebsite"
},
"homepage": "https://github.com/mywebsite",
"devDependencies": {
"concurrently": "^5.3.0",
"nodemon": "^2.0.6"
},
"dependencies": {
"@sendgrid/mail": "^7.4.0",
"animate.css": "^4.1.1",
"bcryptjs": "^2.4.3",
"bootstrap": "^4.5.3",
"colors": "^1.4.0",
"dirname": "^0.1.0",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"express-async-handler": "^1.1.4",
"fs": "0.0.1-security",
"install": "^0.13.0",
"jsonwebtoken": "^8.5.1",
"moment": "^2.29.1",
"mongoose": "^5.10.16",
"morgan": "^1.10.0",
"multer": "^1.4.2",
"mustache": "^4.1.0",
"noty": "^3.2.0-beta",
"path": "^0.12.7",
"postscribe": "^2.0.8",
"react-bootstrap": "^1.4.0",
"react-helmet": "^6.1.0",
"react-hook-form": "^6.14.0",
"react-moment": "^1.1.1",
"react-notification-system": "^0.2.17",
"react-notifications-component": "^3.0.3",
"react-rating-stars-component": "^2.2.0",
"react-script-tag": "^1.1.2",
"react-toastr": "^3.0.0",
"request": "^2.88.2"
}
}