Recently, I have decided to move from Webpacker to Shakapacker. I am using Shakapacker v7.
I am trying to use @svgr/webpack for loading svg images as React Component.
My package.json file looks like
{
"babel": {
"presets": [
"./node_modules/shakapacker/package/babel/preset.js",
"@babel/preset-react"
],
"plugins": [
"@babel/plugin-proposal-class-properties",
"@babel/syntax-dynamic-import",
"@babel/plugin-proposal-object-rest-spread",
"@babel/plugin-transform-runtime"
]
},
"dependencies": {
"@babel/core": "7",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-transform-runtime": "7",
"@babel/preset-env": "7",
"@babel/preset-react": "^7.14.5",
"@babel/runtime": "7",
"@reduxjs/toolkit": "^1.8.4",
"@svgr/webpack": "^8.1.0",
"@tinymce/tinymce-react": "^3.10.1",
"@types/babel__core": "7",
"@types/webpack": "5",
"axios": "^0.21.1",
"babel-loader": "8",
"babel-plugin-transform-class-properties": "^6.24.1",
"bootstrap": "^3.3.7",
"coffeescript": "1.12.7",
"compression-webpack-plugin": "9",
"core-js": "^3.8.3",
"dompurify": "^2.2.6",
"eslint": "^8.34.0",
"improved-yarn-audit": "^3.0.0",
"jest-svg-transformer": "^1.0.0",
"jquery": "^3.5.1",
"jquery-ujs": "^1.2.2",
"lodash": "^4.17.21",
"moment": "^2.29.4",
"postcss-cssnext": "^3.1.1",
"postcss-smart-import": "^0.7.6",
"prop-types": "^15.6.0",
"rc-pagination": "^3.1.17",
"react": "^17.0.2",
"react-big-calendar": "^1.8.2",
"react-bootstrap": "0.33.1",
"react-burger-menu": "^3.0.6",
"react-calendar": "^4.6.0",
"react-datepicker": "^4.6.0",
"react-dom": "^17.0.2",
"react-dropzone": "^14.2.2",
"react-easy-sort": "^1.5.1",
"react-icons": "^4.3.1",
"react-jwt": "^1.1.2",
"react-moment": "^1.1.3",
"react-on-rails": "^10.1.0",
"react-redux": "^8.0.2",
"react-router-dom": "^6.2.2",
"react-scripts": "^5.0.0",
"react-select": "^5.2.2",
"react-switch": "^6.0.0",
"react-tooltip": "^4.2.13",
"shakapacker": "7.2.2",
"slugify": "^1.6.5",
"terser-webpack-plugin": "5",
"webpack": "5",
"webpack-assets-manifest": "5",
"webpack-cli": "4",
"webpack-merge": "5",
"yarn-audit-fix": "^10.0.1"
}
}
my webpack.config.js file looks like
const { merge, generateWebpackConfig } = require('shakapacker')
const path = require('path')
const options = {
resolve: {
extensions: [
'.jsx',
'.mjs',
'.js',
'.ts',
'.tsx',
'.sass',
'.scss',
'.css',
'.module.sass',
'.module.scss',
'.module.css',
'.png',
'.svg',
'.gif',
'.jpeg',
'.jpg',
'.erb',
'.coffee',
'.vue'
],
modules: [
path.join(__dirname, '../../node_modules'),
path.join(__dirname, '../../app/client/bundles')
],
},
module: {
rules: [
{
test: /\.svg$/,
loader: '@svgr/webpack',
options: {
jsx: true
}
}
]
}
}
const webpackConfig = generateWebpackConfig()
module.exports = merge({}, webpackConfig, options)
My React Component looks like
import React from 'react';
import MySvg from './my-svg.svg';
const MyComponent = () => {
return (
<div>
<MySvg />
</div>
);
};
export default MyComponent;
I always gets an error while running above component as
Failed to execute 'createElement' on 'Document': The tag name provided ('/packs/static/images/my-svg-bba2a3d91ed89ztfvbad83.svg') is not a valid name.
Can someone help me figure out what am I doing wrong here? Thanks
After encountering challenges for nearly 2 days, I managed to resolve the issue by implementing the following solution.
Overriding Shakapacker File Rules:
Adding Custom Configuration for @svgr/webpack:
Integration in webpack.config.js:
Ensure to load your custom configuration in the webpack.config.js file:
By applying these changes, you'll effectively override the file rules in Shakapacker and configure Webpack to load SVG files as React components using @svgr/webpack. This setup should address the issues you've encountered. If you have further questions or need additional clarification, feel free to ask!