React Storybook SVG Failed to execute 'createElement' on 'Document'

This is happening because Storybook's default webpack config has its own svg config:

{ 
  test: /\.(svg|ico|jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani)(\?.*)?$/,
  loader: 'file-loader',
  query: { name: 'static/media/[name].[hash:8].[ext]' }
},

I'm pretty sure this is the cause, because you can see the path outlined in error message: query: { name: 'static/media/[name].[hash:8].[ext]' } -> static/media/border.inline.258eb86a.svg

The solution can be to find the existing loader & change / or add an exclude rule to it. Here's an example of a custom .storybook/webpack.config.js:

// storybook 4
module.exports = (_, _, config) => {
// storybook 5
module.exports = ({ config }) => {
  const rules = config.module.rules;

  // modify storybook's file-loader rule to avoid conflicts with your inline svg
  const fileLoaderRule = rules.find(rule => rule.test.test('.svg'));
  fileLoaderRule.exclude = /\.inline.svg$/;

  rules.push({
    test: /\.inline.svg$/,
    ...
    }],
  });

  return config;
};

In Storybook 6, You have to import it like this:

import { ReactComponent as Border } from './images/border.inline.svg'

Try that if it also works for your version since this question is from a year ago.


It appears that Storybook V6 they have changed the default Webpack config. I found that the above answers didn't work for me.

They no longer have an SVG rule, therefore testing for SVG will either error or return back undefined.

There is a oneOf rule on the module.rules which contains a loader without a test as the last rule:

{
      loader: '/Users/alexwiley/Work/OneUp/resources/client/node_modules/react-scripts/node_modules/file-loader/dist/cjs.js',
      exclude: [Array],
      options: [Object]
}

This is the culprit, you need to make sure that the file load is excluding all inline SVG file otherwise it will error.

Add the following to your .storybook/main.js file:

webpackFinal: async(config, { configType }) => {
  config.module.rules.forEach((rule) => {
    if (rule.oneOf) {
      // Iterate over the oneOf array and look for the file loader
      rule.oneOf.forEach((oneOfRule) => {
        if (oneOfRule.loader && oneOfRule.loader.test('file-loader')) {
          // Exclude the inline SVGs from the file loader
          oneOfRule.exclude.push(/\.inline\.svg$/);
        }
      });
      // Push your SVG loader onto the end of the oneOf array
      rule.oneOf.push({
        test: /\.inline\.svg$/,
        exclude: /node_modules/,
        loader: 'svg-react-loader', // use whatever SVG loader you need
      });
    }
  });
  return config;
}