All Projects → based-ghost → react-seo-friendly-spa-template

based-ghost / react-seo-friendly-spa-template

Licence: MIT License
React PWA/SPA template initially scaffolded with CRA (Create React App) and configured for SEO. Makes use of prerendering and other techniques/packages in order to achieve a perfect "Lighthouse Score".

Programming Languages

typescript
32286 projects
SCSS
7915 projects
HTML
75241 projects
javascript
184084 projects - #8 most used programming language
shell
77523 projects

Projects that are alternatives of or similar to react-seo-friendly-spa-template

vue-seo-friendly-spa-template
Vue.js PWA/SPA template initially scaffolded with vue-cli and configured for SEO. Makes use of prerendering and other techniques/packages in order to achieve a perfect "Lighthouse Score".
Stars: ✭ 41 (+70.83%)
Mutual labels:  spa, google-analytics, seo, prerender, netlify, lighthouse, netlify-deployment
Preact Redux Isomorphic
preact-redux-isomorphic PWA SPA SSR best practices and libraries in under 80kB page size (for live demo click the link below)
Stars: ✭ 85 (+254.17%)
Mutual labels:  spa, pwa, seo
Lighthouse Action
💡🏠 GitHub Action for running @GoogleChromeLabs Lighthouse webpage audits
Stars: ✭ 263 (+995.83%)
Mutual labels:  pwa, seo, lighthouse
parcel-plugin-prerender
No description or website provided.
Stars: ✭ 42 (+75%)
Mutual labels:  spa, seo, prerender
Gatsby Advanced Starter
A high performance skeleton starter for GatsbyJS that focuses on SEO/Social features/development environment.
Stars: ✭ 1,224 (+5000%)
Mutual labels:  pwa, seo, netlify
Prerender Spa Plugin
Prerenders static HTML in a single-page application.
Stars: ✭ 7,018 (+29141.67%)
Mutual labels:  spa, seo, prerender
Productivity Frontend
Productivity Application - Kanban Style Productivity Management Application with Customizable Boards, Lists and Cards to Make You More Productive.
Stars: ✭ 234 (+875%)
Mutual labels:  spa, pwa, netlify
cookie
Landing website + Blog using Jekyll & Tailwind CSS
Stars: ✭ 61 (+154.17%)
Mutual labels:  seo, netlify
thvu-blog
My digital home on the internet.
Stars: ✭ 51 (+112.5%)
Mutual labels:  google-analytics, lighthouse
sveltekit-seo
Demo site for SvelteKit SEO showing how to set up meta tags in a SvelteKit blog site.
Stars: ✭ 28 (+16.67%)
Mutual labels:  seo, netlify
nuxt-netlify-lambda-starter
🛠️ SEO-friendly website starter backed by Netlify lambda functions in a simple, friendly repo
Stars: ✭ 60 (+150%)
Mutual labels:  seo, netlify
server-render-javascript
Prerender your javascript web page for better seo with PhantomJS. ⚠️ no es6 supported.
Stars: ✭ 12 (-50%)
Mutual labels:  seo, prerender
testimonial
Jamstack app using Gatsby, Netlify, and FaunaDB.
Stars: ✭ 23 (-4.17%)
Mutual labels:  netlify, netlify-deployment
site-audit-seo
Web service and CLI tool for SEO site audit: crawl site, lighthouse all pages, view public reports in browser. Also output to console, json, csv, xlsx, Google Drive.
Stars: ✭ 91 (+279.17%)
Mutual labels:  seo, lighthouse
wordpress
Free PWA & SPA for Wordpress & Woocommerce
Stars: ✭ 103 (+329.17%)
Mutual labels:  spa, pwa
sparender
基于puppeteer的高性能SPA SEO解决方案
Stars: ✭ 54 (+125%)
Mutual labels:  spa, seo
kanban-project-management
Web Application to manage software development projects.
Stars: ✭ 39 (+62.5%)
Mutual labels:  netlify, netlify-deployment
vuetibook
Integrating Vue.js, Vuetify and Storybook
Stars: ✭ 16 (-33.33%)
Mutual labels:  spa, netlify
badaso
The API & platform builder, build your apps 10x faster even more, it's open source & 100% free !
Stars: ✭ 650 (+2608.33%)
Mutual labels:  spa, pwa
svelte-google-analytics
Google Analytics component for Svelte
Stars: ✭ 41 (+70.83%)
Mutual labels:  google-analytics, seo

react-seo-friendly-spa-template

React PWA/SPA template configured for SEO (initially scaffolded with Create React App).

Features:

  • TypeScript
  • Incorporates styled-components
  • Route transitions handled using react-transition-group
  • Written entirely with React Hooks (no legacy class components)
  • Google analytics management with react-ga
  • Route meta tag management with react-helmet
  • Configured to serve prerendered static HTML with react-snap
  • Custom BackToTop.tsx component that uses react-scroll
  • Custom ToggleTheme.tsx component that handles light/dark theme transitions

Demo

demo

General Overview

This is the React version based on my Vue SEO template which you can find here: vue-seo-friendly-spa-template

Technology Stack Overview

Create React App

initial scaffolding

react-helmet

react-helmet - plugin that allows you to manage your app's meta information. It is a reusable React component that will manage all of your changes to the document head - Helmet takes plain HTML tags and outputs plain HTML tags. It's dead simple, and React beginner friendly.

I have it configured to use one more level of abstraction, where I have the Helmet component and child meta tags broken out to its own component MetaInfo.tsx - referenced at the root of the app i App.tsx to initialize data and then referenced in each route component to override route-specific values (Home.tsx, About.tsx, NotFound404.tsx):

MetaInfo.tsx

import Helmet from 'react-helmet';
import { getRouteMetaInfo } from '../config/routes.config';
import { APP_NAME, DEFAULT_LOCALE, BASE_URL, AUTHOR_NAME } from '../config/env.config';

import type { FunctionComponent } from 'react';
import type { MetaInfoProps } from '../config/routes.config';

const {
  title: DEFAULT_TITLE,
  description: DEFAULT_DESCRIPTION
} = getRouteMetaInfo('Home');

const MetaInfo: FunctionComponent<MetaInfoProps> = ({
  meta = [],
  defer = false,
  lang = DEFAULT_LOCALE,
  title = DEFAULT_TITLE,
  description = DEFAULT_DESCRIPTION
}) => (
  <Helmet
    defer={defer}
    title={title}
    htmlAttributes={{ lang }}
    titleTemplate={`${APP_NAME} | %s`}
    meta={[
      {
        name: 'description',
        content: description
      },
      {
        property: 'og:description',
        content: description
      },
      {
        property: 'og:title',
        content: title
      },
      {
        property: 'og:type',
        content: 'website'
      },
      {
        property: 'og:image',
        content: `${BASE_URL}logo192.png`
      },
      {
        name: 'author',
        content: AUTHOR_NAME
      }
    ].concat(meta)}
  />
);

export default MetaInfo;

...and used in About component

import { Alert, MetaInfo } from '../../components';
import { getRouteMetaInfo } from '../../config/routes.config';

import type { FunctionComponent } from 'react';

const About: FunctionComponent = () => (
  <div className="container view-wrapper">
    <MetaInfo {...getRouteMetaInfo('About')} />
    <Alert
      title="About Page"
      alertAnimation="rubberBand_animation 1s"
      subTitle="Very interesting information may go here."
    />
  </div>
);

export default About;

react-ga

react-ga - This is a JavaScript module that can be used to include Google Analytics tracking code in a website or app that uses React for its front-end codebase. It does not currently use any React code internally, but has been written for use with a number of Mozilla Foundation websites that are using React, as a way to standardize our GA Instrumentation across projects.

My preferred configuration - in a custom hook that initializes your google analytics settings and contains an effect that reacts to the location object that is retrieved from the referenced react-router-dom hook useLocation - usePageTracker.ts:

import ReactGA from 'react-ga';
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import { routes } from '../config/routes.config';
import { IS_PRODUCTION } from '../config/env.config';

// Initialize the react-ga plugin using your issued GA tracker code + options
ReactGA.initialize('UA-000000-01', {
  debug: !IS_PRODUCTION,
  gaOptions: {
    cookieFlags: 'max-age=7200;secure;samesite=none'
  }
});

// Define custom hook to handle page tracking
const usePageTracker = (): void => {
  const location = useLocation();

  useEffect(() => {
    const { pathname, search } = location;
    const isValidPath = routes.some((x) => x.path === pathname);

    if (isValidPath) {
      const page = pathname + search;
      ReactGA.set({ page });
      ReactGA.pageview(page);
    }
  }, [location]);
};

export default usePageTracker;

...and then use that hook in the root of the application tree:

e.g. in the App.tsx component

import Layout from './Layout';
import { routes } from './config/routes.config';
import { MetaInfo, NotFound404 } from './components';
import { usePageTracker, useScrollToTop } from './hooks';
import { useLocation, Route, Routes } from 'react-router-dom';
import { CSSTransition, SwitchTransition } from 'react-transition-group';

import type { FunctionComponent } from 'react';

const App: FunctionComponent = () => {
  useScrollToTop();
  usePageTracker();

  const location = useLocation();
  const cssKey = location.pathname?.split('/')[1] || '/';

  return (
    <Layout>
      <MetaInfo />
      <SwitchTransition mode="out-in">
        <CSSTransition
          key={cssKey}
          timeout={250}
          classNames="fade"
        >
          <Routes location={location}>
            {routes.map(({ path, Component }) => (
              <Route
                key={path}
                path={path}
                element={<Component />}
              />
            ))}
            <Route
              path="*"
              element={<NotFound404 />}
            />
          </Routes>
        </CSSTransition>
      </SwitchTransition>
    </Layout>
  );
};

export default App;

react-snap

react-snapshot - Pre-renders a web app into static HTML. Uses Headless Chrome to crawl all available links starting from the root. Heavily inspired by prep and react-snapshot, but written from scratch. Uses best practices to get the best loading performance.

Configured in two simple steps:

Added following entry to package.json:

"scripts": {
  "postbuild": "react-snap"
}

And then in src/index.tsx:

import { hydrate, render } from 'react-dom';
import { StrictMode } from 'react';
import { BrowserRouter } from 'react-router-dom';
import App from './App';

const appElement = (
  <StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </StrictMode>
);

const rootElement = document.getElementById('root');
const hasChildNodes = !!rootElement?.hasChildNodes();

hasChildNodes
  ? hydrate(appElement, rootElement)
  : render(appElement, rootElement);

Scripts

npm install

After cloning the repo, run this command. This will:

  • Install Node dependencies from package.json

npm run start

To start the app (development build), run this command. This will:

  • Compile the app and run on the development server

npm run test

  • Execute any Jest tests (based on your configration)

npm run sitemap

  • This command will execute code in the sitemap-generator.js. Using the sitemapUrl parameter defined in that file (should reflect your registered domain name) a sitemap.xml is generated and persisted under the 'public' folder - this file is referenced in the robots.txt file. This uses the sitemap-generator package.

npm run build

This script will:

  • Build release Webpack bundles and run react-snapshot to serve prerendered static files
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].