React Netlify No Plugins

Full Stack Developed by: Donald Boulton Follow Don on Twitter🙌 0
Jul 6, 2019 min readNetlify, CMS, Identity, Widget  Category Tech


🔌 I started using React within Jekyll in March and I was already using netlify and Netlify Identity and Netlify CMS for my personal website so I picked 🔗 react + Netlify CMS Starter for my first react Project, and it was slower than some of the other starters I messed around with.

Identify Widget

React configurations and plugin "netlify-identity-widget", slowed my react site down even more, Netlify CMS and Netlify Identity Widget both are processed and build with react, which is not needed like a lot of react Plugins.

I stripped Netlify CMS and Netlify identity out of react-config.js plugins and any related plugins out of my package.json and any config references to them and now my react site is super fast like its supposed to be, even with cookie consent, Google adds, including analytics tracking from HotJar, CookieConsent and Google. = all external scripts with out any react plugins I inject preload them in my react Netlify configuration for the react-plugin-netlify in react-config.

Identity Webpack Config

If you are going to use the identity widget npm package then tell react not to build it, as you should do with any stand alone precompiled js, "like Netlify CMS". Add them as an array.

// FIX in react-node.js netlify-identity-widget server rendering ... @2018/12/12
exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
  if (stage === "build-html") {
      module: {
        rules: [
            test: /netlify-identity-widget/,
            use: loaders.null(),
}// end of onCreateWebpackConfig

react Config

   resolve: `react-plugin-netlify`,
      options: {
        headers: {
          '/*': [
            'Link: <
            adsbygoogle.js>; rel=preload; as=script',
            'Link: <>; 
            rel=preload; as=script',
            'Link: <>; 
            rel=preload; as=script',
          '/blog/*': [
            'Link: <>; 
            rel=preload; as=script',
          '/*.js': [
            'cache-control: public, max-age=31536000, immutable',
          '/*.css': [
            'cache-control: public, max-age=31536000, immutable',
          '/sw.js': [
            'cache-control: public, max-age=0, must-revalidate',

I had incorporated Netlify CMS and Identity into a Jekyll site and did a custom build for Netlify CMS and Netlify Identity widget with my own styling and custom builds, Separate from my Jekyll build so I knew it could be done in react without plugins.

I liked having the ability to edit my pages and posts remotely from maybe a library computer and Netlify CMs works great for me in my react site but not in my react build.

I Forked both Netlify CMS and Identity customized them and added the necessary Custom Webpack builds of each to my /static/admin folder and added them to my index.html admin file.

For Netlify Identity on the front end I added a folder to my Components as NetlifyIdentity and used the custom build script and its .map file for the Identify Widget service.

Building this post

Netlify CMS building this post

Adding to my NavBar

import NetlifyIdentityWidget from '../IdentityWidget'

// and then the component to the navbar links

  <div className='navbar-item' id='login'>
    <NetlifyIdentityWidget />

Moving the CMS folder that came with the react Netlify Starter, with the, "cms.js and preview templates", to the /static/admin/cms folder.

Code index.html

Repo Link

<!doctype html><html lang="en" class="no-js" itemscope 
<head>  <script src="./index.js"></script>  <script src="./netlify-identity.js"></script>  <script>

  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", function () {
        APIUrl: ""
  } else {
      APIUrl: ""
  <title>Content Manager</title>

<body id="style-3" class="body" auth-false" itemscope 
itemtype=""><div class="page">    <script src="./netlify-cms.js"></script>    <script src="../admin/cms/cms.js"></script>

    // Internal id of the component
    id: "youtube",
    // Visible label
    label: "Youtube",
    // Fields the user need to fill out when adding an instance of the component
    fields: [{name: 'id', label: 'Youtube Video ID', widget: 'string'}],
    // Pattern to identify a block as being an instance of this component
    pattern: /^youtube (\S+)$/,
    // Function to extract data elements from the regexp match
    fromBlock: function(match) {
      return {
        id: match[1]
    // Function to create a text block from an instance of this component
    toBlock: function(obj) {
      return 'youtube ' +;
    // Preview output for this component. Can either be a string or a React component
    // (component gives better render performance)
    toPreview: function(obj) {
      return (
        '<img src="' + + '/maxresdefault.jpg" alt="Youtube Video"/>'
<script charset="utf-8" src="//"></script>
  UPLOADCARE_TABS = "file url facebook gdrive gphotos dropbox instagram evernote flickr skydrive";
<script src="../admin/cms/preview-templates/HomePagePreview.js"></script> 
<script src="../admin/cms/preview-templates/AboutPagePreview.js"></script>
<script src="../admin/cms/preview-templates/ArticlePagePreview.js"></script>
<script src="../admin/cms/preview-templates/PricingPagePreview.js"></script>
<script src="../admin/cms/preview-templates/ContactPagePreview.js"></script>
<script src="../admin/cms/preview-templates/PrivacyPagePreview.js"></script>

  var PostPreview = createClass({
      render: function() {
        var entry = this.props.entry;
        var image = entry.getIn(['data', 'image']);
        var bg = image && this.props.getMedia(image);
        return h('div', {},
          h('div', {className: "hero"},
            h('h1', {}, entry.getIn(['data', 'title'])),
            bg ? h('img', {src: bg.toString()}) : null
          h('p', {},
            h('small', {}, "Written " + entry.getIn(['data', 'date']))
          h('div', {"className": "text"}, this.props.widgetFor('body'))
    CMS.registerPreviewTemplate('home', HomePagePreview)
    CMS.registerPreviewTemplate('about', AboutPagePreview)
    CMS.registerPreviewTemplate('pricing', PricingPagePreview)
    CMS.registerPreviewTemplate('contact', ContactPagePreview)
    CMS.registerPreviewTemplate('privacy', PrivacyPagePreview)
    CMS.registerPreviewTemplate('blog', ArticlePreview)
    export default {

CMS index file

Then a index.js file to import and export the Netlify CMS

import CMS from '../admin/cms/cms'
export default {

External Images

I am using an external service for my Images with uploadcare or you can use cloudinary library and not have to use all the plugins slowing your react build and site speed; "like, "react-plugin-netlify-cms' and "react-plugin-netlify-identity-widget" "react-remark-relative-images", "react-remark-copy-linked-files", "netlify-cms-app", netlify-cms-media-library-cloudinary", "netlify-cms-media-library-uploadcare". No does react have to care about uploaded files or folder configurations for static uploads and/or images in gatbsy.config.

Just include any custom code or external libraries in you CMS or Identity Builds.

I added the preview styles from my Netlify build style sheet using styled components and Bluma with a custom override style sheet on stock Bluma styles for my react Site, so I used my production style sheet i n my admin folder as



Here is an example of not using MDX Plugins, but only using remark-rehype with HTMLAst to render a component in markdown pages.



My repo holds all the code for the discussion above at 🔗 DWB publislogic repo


Bring your team together with Slack, Work collaboration hub.

MailChimp Newsletters
MailChimp Newsletters

Enjoyed this post? Subscribe!
Css Tricks

Front-End UI, Javascript & Functions, HTML Tips, and More!