anoop francis
anoop francis

Reputation: 157

Convert my create react app typescript to ssr for serving dynaminc meta tags

I want to convert my create react app typescript to ssr for serving dynamic meta tags so social medial crawlers can show preview. Has anyone done this, can share a sample code with all the config

this is my index.tsx

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

ReactDOM.hydrate(
 <React.StrictMode>
  <App />
 </React.StrictMode>,
document.getElementById('root')
);

my server.ts

import express from "express";
import React from "react";
import {renderToString} from "react-dom/server";
import App from '../src/App'

import * as path from 'path';
import * as fs from 'fs'
import { getArticle } from "../src/api";
const app = express();


app.use(express.static("public"));
const PORT = process.env.PORT || 3006;

const indexPath = path.resolve(__dirname,'..','public','index.html')

const readIndexHtml = () => {
    let response
    fs.readFile(indexPath,'utf8',(err,html) => {
        if(err) {
            console.error('Error during file reading', err);
            // return res.status(404).end()
            throw err
        }
    response = html
    })
    return response
}

app.get('/',(req,res) => {
    try {
        let htmlData = readIndexHtml()  
        htmlData = (htmlData  as string)
        .replace('__META_OG_TITLE__', "title")
        .replace('__META_OG_DESCRIPTION__', "description")
        .replace('__META_DESCRIPTION__', "desc")  
        return res.send(htmlData);  
    } catch (error) {
        console.log('erro while reading ' , error)
        return res.status(404).end()
    }

})

app.get('/article/:id', async(req,res) => {
    let id = req.params.id
    try {
        let response = await getArticle(parseInt(id))
        try {
            let htmlData = readIndexHtml()  
            htmlData = (htmlData  as string)
            .replace('__META_OG_TITLE__', response.data['heading'])
            .replace('__META_OG_DESCRIPTION__', response.data['shortDescription'])
            .replace('__META_DESCRIPTION__', response.data['shortDescription'])   
            return res.send(htmlData);  
        } catch (error) {
            console.log('erro while reading ' , error)
            return res.status(404).end()
        }       
    } catch (error) {
        console.log('erro while fetching article ' , error)
        return res.status(404).end()
    }

})

app.listen(PORT, () => {
    return console.log(`server is  listening on ${PORT}`);
  });

My Package.json

{
  "name": "react-anoop-study",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.14.1",
    "@testing-library/react": "^11.2.7",
    "@testing-library/user-event": "^12.8.3",
    "@types/jest": "^26.0.24",
    "@types/node": "^12.20.15",
    "@types/react": "^17.0.13",
    "@types/react-dom": "^17.0.8",
    "axios": "^0.21.1",
    "jsx-runtime": "^1.2.0",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-helmet": "^6.1.0",
    "react-router-dom": "^5.2.0",
    "react-scripts": "4.0.3",
    "react-toggle": "^4.1.2",
    "typescript": "^4.3.5",
    "web-vitals": "^1.1.2"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@types/node": "^12.20.26",
    "@types/react": "^17.0.22",
    "@types/react-helmet": "^6.1.2",
    "@types/react-router-dom": "^5.1.8",
    "@types/react-toggle": "^4.0.3"
  }
}

What are the packages and configurations I need to add to make the dynamic changes possible

My project structure

├───public
├───server
└───src
    ├───api
    ├───components
    │   ├───carousel
    │   ├───flexboxtitle
    │   └───paper
    ├───pages
    │   ├───about
    │   ├───article
    │   └───carouseldemo
    └───style
        ├───component
        └───pages

Upvotes: 2

Views: 1052

Answers (1)

Aditya Jha
Aditya Jha

Reputation: 120

Easiest way of doing this is by migrating to next.js https://nextjs.org/docs/migrating/from-create-react-app

Upvotes: 2

Related Questions