From e467e7089740182f93ead44735cdb087e741dc53 Mon Sep 17 00:00:00 2001 From: sebastian correa Date: Fri, 5 Feb 2021 11:19:13 -0500 Subject: [PATCH 1/4] react-helmet clientside --- package-lock.json | 30 ++++++++++++++++++++++++++++++ package.json | 4 +++- src/App.tsx | 8 ++++++++ src/Home.tsx | 5 +++++ 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index ab96959..186f5b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2393,6 +2393,15 @@ "@types/react": "^16" } }, + "@types/react-helmet": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/react-helmet/-/react-helmet-6.1.0.tgz", + "integrity": "sha512-PYRoU1XJFOzQ3BHvWL1T8iDNbRjdMDJMT5hFmZKGbsq09kbSqJy61uwEpTrbTNWDopVphUT34zUSVLK9pjsgYQ==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/react-router": { "version": "5.1.11", "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.11.tgz", @@ -12824,6 +12833,22 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.8.tgz", "integrity": "sha512-HvPuUQnLp5H7TouGq3kzBeioJmXms1wHy9EGjz2OURWBp4qZO6AfGEcnxts1D/CbwPLRAgTMPCEgYhA3sEM4vw==" }, + "react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" + }, + "react-helmet": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz", + "integrity": "sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==", + "requires": { + "object-assign": "^4.1.1", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.1.1", + "react-side-effect": "^2.1.0" + } + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -12880,6 +12905,11 @@ "tiny-warning": "^1.0.0" } }, + "react-side-effect": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.1.tgz", + "integrity": "sha512-2FoTQzRNTncBVtnzxFOk2mCpcfxQpenBMbk5kSVBg5UcPqV9fRbgY2zhb7GTWWOlpFmAxhClBDlIq8Rsubz1yQ==" + }, "read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", diff --git a/package.json b/package.json index e9e87d0..747d6ec 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "react-app-polyfill": "^2.0.0", "react-dev-utils": "^11.0.1", "react-dom": "^17.0.1", + "react-helmet": "^6.1.0", "react-refresh": "^0.8.3", "react-router": "^5.1.2", "react-router-dom": "^5.1.2", @@ -82,7 +83,7 @@ "start": "node scripts/start.js", "build": "node scripts/build.js", "builds": "node scripts/buildserver.js", - "b": "npm run build && npm run builds", + "b": "npm run build && npm run builds && npm run dr", "test": "node scripts/test.js", "d": "node --inspect-brk scripts/build.js", "ds": "node --inspect-brk scripts/buildserver.js", @@ -173,6 +174,7 @@ "@loadable/webpack-plugin": "^5.14.0", "@types/loadable__component": "^5.13.1", "@types/loadable__server": "^5.12.3", + "@types/react-helmet": "^6.1.0", "@types/react-router-dom": "^5.1.7", "copyfiles": "^2.4.1", "patch-package": "^6.2.2" diff --git a/src/App.tsx b/src/App.tsx index 019bd48..b09bb4e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -3,6 +3,8 @@ import './App.css'; import { BrowserRouter, StaticRouter, Route, Link } from "react-router-dom"; import Home from "./Home" import { ChunkExtractorManager } from '@loadable/server' +import {Helmet} from "react-helmet"; + // eslint-disable-next-line import/no-extraneous-dependencies import loadable from '@loadable/component' @@ -12,6 +14,9 @@ const A = loadable(() =>{ const Category = () => (
+ + Category title +

Category

under Category

@@ -20,6 +25,9 @@ const Category = () => ( const Products = () => (
+ + Products title +

Products

); diff --git a/src/Home.tsx b/src/Home.tsx index 983c455..475ec0a 100644 --- a/src/Home.tsx +++ b/src/Home.tsx @@ -2,10 +2,15 @@ import React from 'react'; import logo from './logo.svg'; import Sebas from 'component-sebas' +import {Helmet} from "react-helmet"; + const Home =() =>{ return (
+ + Home title +
logo

From d90211a232dbf9e860b15501c334f65b6f227e2a Mon Sep 17 00:00:00 2001 From: sebastian correa Date: Fri, 5 Feb 2021 11:40:20 -0500 Subject: [PATCH 2/4] getting the helmet data --- config/run.js | 6 +++++- src/server/index.tsx | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/config/run.js b/config/run.js index 5c389d2..ecaf9c6 100644 --- a/config/run.js +++ b/config/run.js @@ -5,6 +5,7 @@ const statsFile = path.resolve('build/server/loadable-stats.json') // We create an extractor from the statsFile const extractor = new lServer.ChunkExtractor({ statsFile }) const fs = require('fs'); +const {Helmet} = require('react-helmet') const express = require('express'); @@ -34,7 +35,10 @@ const all = (req, res)=>{ res.writeHead(200, { 'Content-Type': 'text/html' }) console.log(`SSR of ${req.path}`); - const reactDom = moduleWithfault.default(extractor,location ) + const [reactDom, helmet] = moduleWithfault.default(extractor,location ) + // const helmet = Helmet.renderStatic(); + console.info('title', helmet.title.toString()) + return res.end( htmlData.replace( '

', diff --git a/src/server/index.tsx b/src/server/index.tsx index 23e1a78..1d56393 100644 --- a/src/server/index.tsx +++ b/src/server/index.tsx @@ -1,12 +1,14 @@ import React from 'react' import {renderToString} from 'react-dom/server' import App from '../App' ; +import Helmet from 'react-helmet' const renderK = (extractor: any, location?: string) =>{ const reactDom = renderToString() + const helmet = Helmet.renderStatic(); console.log("🚀 ------------------------------------------------------------") console.log("🚀 ~ file: index.tsx ~ line 10 ~ renderK ~ reactDom", reactDom) console.log("🚀 ------------------------------------------------------------") @@ -18,7 +20,7 @@ const renderK = (extractor: any, location?: string) =>{ // // And you can even collect your style tags (if you use "mini-css-extract-plugin") // const styleTags = extractor.getStyleTags() // or extractor.getStyleElements(); - return reactDom + return [reactDom, helmet] } From c9e215fa47196a178263528e7a30813d2a8b809a Mon Sep 17 00:00:00 2001 From: sebastian correa Date: Fri, 5 Feb 2021 12:06:51 -0500 Subject: [PATCH 3/4] replace title with helmet static --- config/run.js | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/config/run.js b/config/run.js index ecaf9c6..ed3b059 100644 --- a/config/run.js +++ b/config/run.js @@ -5,12 +5,11 @@ const statsFile = path.resolve('build/server/loadable-stats.json') // We create an extractor from the statsFile const extractor = new lServer.ChunkExtractor({ statsFile }) const fs = require('fs'); -const {Helmet} = require('react-helmet') - const express = require('express'); const PORT = 3000; +const helmetExtractorRegex = /(.+)<\/title>/ // const routes = ['/', '/page']; @@ -37,10 +36,24 @@ const all = (req, res)=>{ const [reactDom, helmet] = moduleWithfault.default(extractor,location ) // const helmet = Helmet.renderStatic(); - console.info('title', helmet.title.toString()) + const helmetTitle= helmet.title.toString() + console.info('title', helmetTitle) + + const hasHelmetTitle = helmetTitle ? helmetTitle.match(helmetExtractorRegex): null + console.info('hasHelmetTitle', hasHelmetTitle) + + + if(hasHelmetTitle){ + htmlData= htmlData + .replace( + /\s*<title>(.+)<\/title>\s*/, + helmetTitle + ) + } return res.end( - htmlData.replace( + htmlData + .replace( '<div id="root"></div>', `<div id="root">${reactDom}</div>` ) From c66032ca475aeb293ed3adde5c6c849961e01ed3 Mon Sep 17 00:00:00 2001 From: sebastian correa <sebastian@sawyereffect.com> Date: Fri, 5 Feb 2021 12:07:51 -0500 Subject: [PATCH 4/4] clean the log statement --- config/run.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/config/run.js b/config/run.js index ed3b059..2126481 100644 --- a/config/run.js +++ b/config/run.js @@ -35,13 +35,8 @@ const all = (req, res)=>{ console.log(`SSR of ${req.path}`); const [reactDom, helmet] = moduleWithfault.default(extractor,location ) - // const helmet = Helmet.renderStatic(); const helmetTitle= helmet.title.toString() - console.info('title', helmetTitle) - const hasHelmetTitle = helmetTitle ? helmetTitle.match(helmetExtractorRegex): null - console.info('hasHelmetTitle', hasHelmetTitle) - if(hasHelmetTitle){ htmlData= htmlData