From 646f87d4febeb56eacd26ef1f195e9a1ea5cee04 Mon Sep 17 00:00:00 2001 From: Ruggero Castagnola Date: Sat, 15 Dec 2018 10:24:57 +0100 Subject: [PATCH 1/3] Added Readme FAQ on how to set up SEO using react-snap and react-helmet --- README.md | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6b39f38e..248f8b44 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ but significant amounts of code were rewritten and simplified. Here are some shi - [I need to support IE11. What do I do?](#faq) - [How do I use a web worker?](#faq) - [How do I use a service worker?](#faq) + - [I need title and meta tags for each route for SEO. How do I do it?](#faq) - [Contributing](#contributing) ## Creating a new project @@ -562,7 +563,134 @@ If you just need the app to work offline, use the [offline-plugin](https://githu Otherwise, put the `service-worker.js` file in the `public/` folder, and register it normally. +
+I need title and meta tags for each route for SEO. How do I do it? + +You can use [`react-helmet`](https://github.com/nfl/react-helmet) to dynamically add html tags to the `` of a document and [`react-snap`](https://github.com/stereobooster/react-snap) to prerender them statically after the build process is complete. Here's how to configure them. + +## Install `react-helmet` and `react-snap` +`yarn add react-helmet react-snap` + +## Add meta tags for each route in the `render` function +As specified in the [`react-helmet` documentation](https://github.com/nfl/react-helmet). E.g. + +``` +export default class Home extends React.Component { + render() { + return ( + + Home title + + {/* Google */} + + + + {/* Facebook */} + + + + + + + {/* Twitter */} + + + + + + + {/* Chrome for Android */} + + + +
+ {/* Homepage content */} +
+ ) + } +} +``` + +Please note that some of these meta can be put directly in `src/index.html`, as they are probably the same for all pages. Specifically, `copyright`, `og:type`, `twitter:card`, `twitter:site`. + +## Add `react-snap` in `src/index.js` +``` +import {render, hydrate} from 'react-dom' + renderApp() + function renderApp() { + if (rootElement.hasChildNodes()) { + hydrate(, rootElement) + } else { + render(, rootElement) + } +} +``` + +## Add `react-snap` to `package.json` +``` +"scripts": { + ... + "postbuild": "react-snap" +}, +"reactSnap": { + "puppeteerArgs": [ + "--no-sandbox" + ] +} +``` + +Note: the puppeteerArgs avoid the build to break on the Bitbucket pipelines. + +## Add the `react-snap` config in `bitbucket-pipelines.yml` +Add it in `script`, right before `git clone --branch="master"` ... + +``` +- apt-get update; apt-get install -y gettext-base; +- echo 'deb http://dl.google.com/linux/chrome/deb/ stable main' > /etc/apt/sources.list.d/chrome.list +- wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - +- set -x && apt-get update && apt-get install -y xvfb google-chrome-stable +- wget -q -O /usr/bin/xvfb-chrome https://bitbucket.org/atlassian/docker-node-chrome-firefox/raw/ff180e2f16ea8639d4ca4a3abb0017ee23c2836c/scripts/xvfb-chrome +- ln -sf /usr/bin/xvfb-chrome /usr/bin/google-chrome +- chmod 755 /usr/bin/google-chrome +``` + +## OK, setup done! Now, how do I check if it is working? +Run `yarn build`. After the build is complete, you will see some folders with an `index.html` file in them. Also `react-snap` shows its progress in the terminal right after `yarn build` task is complete. + +## Basic troubleshooting: `react-snap` works properly, but no links are found +You probably forgot to add `` to the page. React-snap renders all pages looking for `` tags. It then follows the `href` to render the subsequent pages. If no `` tags are found, then no links are crawled. +This is particularly important, as some routers hide their logic in an `onClick` event handler, and don't compile your links to actual `` tags by default (e.g. `mobx-state-router`). + +## Basic troubleshooting: I get a weird error for 404 pages +On 404 pages, `react-snap` requires you to have the string `404` to be part of the ``, such as +``` +<title>404 - Page not found +``` + +In the future, it might be possible to overcome this limitation (for this, follow [#91](https://github.com/stereobooster/react-snap/issues/91)) + +## Basic troubleshooting: There is unknown code in my built index.html. Is it malicious? How do I remove it? +Most likely, it is one of the third party scripts you included in the bundle. For example, when one includes Google Tag Manager, `react-snap` executes the script and the result is put into the `index.html`. + +If this is not what you wish, you can avoid `react-snap` executing that function like this: + +``` +const isSnap = navigator.userAgent === 'ReactSnap' +if(!isSnap) { + // Google Tag Manager IIFE goes here +} +``` + +For more info on this, please see [userAgent](https://github.com/stereobooster/react-snap#useragent) on the `react-snap` documentation + +## Further troubleshooting +Please, refer to the documentations for [`react-helmet`](https://github.com/nfl/react-helmet) and [`react-snap`](https://github.com/stereobooster/react-snap). + +## What goes in the ``? +Please, see [`@joshbuchea`'s head repo](https://gethead.info/). +
+ ## Contributing If you make some edits and wish to test them locally you can run `yarn create-test-app` which creates a test app using the local packages. -To publish the updated packages, run `yarn run publish`, lerna will detect the packages you changed and ask you for the new version number. +To publish the updated packages, run `yarn run publish`, lerna will detect the packages you changed and ask you for the new version number. \ No newline at end of file From 54484b67b0a35eff99c545721956031fa2ec617c Mon Sep 17 00:00:00 2001 From: Ruggero Castagnola Date: Sat, 15 Dec 2018 10:30:15 +0100 Subject: [PATCH 2/3] Added syntax highlighting --- .prettierignore | 1 + README.md | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.prettierignore b/.prettierignore index 04c17478..d8b71383 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,2 +1,3 @@ package.json node_modules/ +README.md \ No newline at end of file diff --git a/README.md b/README.md index 248f8b44..14fa2c27 100644 --- a/README.md +++ b/README.md @@ -574,7 +574,7 @@ You can use [`react-helmet`](https://github.com/nfl/react-helmet) to dynamically ## Add meta tags for each route in the `render` function As specified in the [`react-helmet` documentation](https://github.com/nfl/react-helmet). E.g. -``` +```js export default class Home extends React.Component { render() { return ( @@ -614,10 +614,12 @@ export default class Home extends React.Component { Please note that some of these meta can be put directly in `src/index.html`, as they are probably the same for all pages. Specifically, `copyright`, `og:type`, `twitter:card`, `twitter:site`. ## Add `react-snap` in `src/index.js` -``` +```js import {render, hydrate} from 'react-dom' - renderApp() - function renderApp() { + +renderApp() + +function renderApp() { if (rootElement.hasChildNodes()) { hydrate(, rootElement) } else { @@ -627,7 +629,7 @@ import {render, hydrate} from 'react-dom' ``` ## Add `react-snap` to `package.json` -``` +```json "scripts": { ... "postbuild": "react-snap" @@ -644,7 +646,7 @@ Note: the puppeteerArgs avoid the build to break on the Bitbucket pipelines. ## Add the `react-snap` config in `bitbucket-pipelines.yml` Add it in `script`, right before `git clone --branch="master"` ... -``` +```yml - apt-get update; apt-get install -y gettext-base; - echo 'deb http://dl.google.com/linux/chrome/deb/ stable main' > /etc/apt/sources.list.d/chrome.list - wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - @@ -663,7 +665,7 @@ This is particularly important, as some routers hide their logic in an `onClick` ## Basic troubleshooting: I get a weird error for 404 pages On 404 pages, `react-snap` requires you to have the string `404` to be part of the ``, such as -``` +```html <title>404 - Page not found ``` @@ -674,7 +676,7 @@ Most likely, it is one of the third party scripts you included in the bundle. Fo If this is not what you wish, you can avoid `react-snap` executing that function like this: -``` +```js const isSnap = navigator.userAgent === 'ReactSnap' if(!isSnap) { // Google Tag Manager IIFE goes here From 1ce9f8eaba9c5c1156b84f0f4a4bfcb6f125b7b6 Mon Sep 17 00:00:00 2001 From: Ruggero Castagnola Date: Sat, 15 Dec 2018 10:33:09 +0100 Subject: [PATCH 3/3] Removed readme from prettierignore --- .prettierignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.prettierignore b/.prettierignore index d8b71383..170b81ef 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,2 @@ package.json -node_modules/ -README.md \ No newline at end of file +node_modules/ \ No newline at end of file