Utilize an SVG file using the <svg> tag in a React application.
The application fails to compile with nx serve.
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
I personally discovered this when trying to use the Ionic React components in an Nx workspace, so will provide these steps to reproduce.
yarn install @ionic/reactapp.tsx JSX with <IonApp></IonApp>nx serveIf you can provide steps to reproduce from scratch, that would be enormously appreciated (i.e. where the first step is npx create-nx-workspace@latest repro-workspace)
Please provide any relevant information about your setup:
ERROR in /Users/devinshoemaker/code/ionic/test-nx-ionic/node_modules/ionicons/dist/ionicons/svg/md-quote.svg 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M96.4 416h77.1l50.9-96.6V96h-160v223.4h77.1L96.4 416zm224 0h77.1l50-96.6V96H288.4v223.4h82l-50 96.6z"/></svg>
ERROR in /Users/devinshoemaker/code/ionic/test-nx-ionic/node_modules/ionicons/dist/ionicons/svg/ios-school.svg 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M96.9 270.3V363c0 2.9 1.5 5.5 4 7l132 75.9c5.3 3.1 12-.8 12-7v-93.8c0-2.9-1.5-5.5-4-7l-132-74.9c-5.4-2.9-12 1-12 7.1zM280.9 445.9L413 370c2.5-1.4 4-4.1 4-7v-93.7c0-6.2-6.6-10-12-7l-132 75.9c-2.5 1.4-4 4.1-4 7V439c-.1 6.1 6.6 10 11.9 6.9z"/><path d="M249 65.1L37 188.9c-5.4 3.1-5.4 10.8 0 13.9l212 117.8c4.9 2.8 11 2.8 15.9 0L453 212.9c5.3-3.1 7 .8 7 7v153.4c0 6.8 3.9 10 11 10 4.4 0 10-3.2 10-10V201.5c0-2.9-1.5-5.5-4-7L264.9 65.1c-4.9-2.8-11-2.8-15.9 0z"/></svg>
ERROR in /Users/devinshoemaker/code/ionic/test-nx-ionic/node_modules/ionicons/dist/ionicons/svg/md-arrow-round-down.svg 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M99.4 284.9l134 138.1c5.8 6 13.7 9 22.4 9h.4c8.7 0 16.6-3 22.4-9l134-138.1c12.5-12 12.5-31.3 0-43.2-12.5-11.9-32.7-11.9-45.2 0l-79.4 83v-214c0-16.9-14.3-30.6-32-30.6-18 0-32 13.7-32 30.6v214l-79.4-83c-12.5-11.9-32.7-11.9-45.2 0s-12.5 31.2 0 43.2z"/></svg>
I have found one other person that reported a similar issue, though it's not Ionic specific. The solution proposed here involved overriding the default webpack config that Nx uses for it's React applications, however that config did not work for me, and I am not adept enough with webpack yet to get this working. I have been inspecting the create-creact-app webpack.config.js (which is what Ionic uses in it's generated projects) and will continue to try and get an override working, but this does seem like something that should be available out of the box. create-react-app applications are quite popular, so I imagine many people will eventually run into this issue when using React with Nx.
https://stackoverflow.com/questions/56848952/cannot-load-svg-in-nrwl-react-workspace
I struggled with this yesterday and resorted to just using the file's path as the src attribute
Thanks for the response, it's nice to know that I'm not alone. I'm glad that worked for you, but that's a bummer for my situation as I cannot control what Ionic does.
Some of the solutions I found were adding a custom.d.ts file in the root of the project and including:
declare module '*.svg' {
const content: string;
export default content;
}
And/or using a custom webpack config with a loader for svg's etc.
There a few solutions floating around that seem to be working for others, but nothing worked for me. I'll be keeping an eye on this issue since I'd prefer to be able to import them directly.
@devinshoemaker
I had the same problem during integrating Nx and @ionic/react and I solved it by using a custom webpack config.
$ npm i @ionic/react @ionic/react-router react-router-dom ionicons
$ npm i -D [email protected]
$ npm i -D @svgr/webpack url-loader
// @nrwl/react + SVG
const babelWebpackConfig = require('@nrwl/react/plugins/babel');
module.exports = config => {
config.module.rules.push(
{
test: /\.svg$/,
use: [
'@svgr/webpack',
'url-loader'
]
}
);
return babelWebpackConfig(config);
};
{
"version": 1,
"projects": {
"client": {
"root": "apps/client",
"sourceRoot": "apps/client/src",
"projectType": "application",
"schematics": {},
"architect": {
"build": {
"builder": "@nrwl/web:build",
"options": {
...
"webpackConfig": "./webpack.config.js"
},
@ionic/react)(window as any).process = {
env: {}
};
@puku0x Thanks! This worked for me without the polyfill.ts (but i'm not using ionic, so maybe thats it)
I tried a couple of different webpack.config.js variations, but no worked. Thanks for yours, works like a charm!
@puku0x Hey thanks for the workaround. We can add SVG support in the web builder so any app using it will benefit -- including React.
What is the polyfill entry for? Do you get an error without it?
@jaysoo Thank you. I am looking forward to supporting SVG. Actually, the polyfill is needed only for Ionic React because it requires process.env to detect development mode.

@puku0x Hmm, the build already replaces process.env.NODE_ENV with production or development, but looks like ionic is looking for process.env which we don't substitute. This can be fixed as well. :)
In addition, as mentioned in Jest Docs, a file mock is needed to run tests.
// jest.config.js
module.exports = {
testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'],
transform: {
'^.+\\.(ts|js|html)$': 'ts-jest',
},
resolver: '@nrwl/jest/plugins/resolver',
moduleFileExtensions: ['ts', 'js', 'html'],
coverageReporters: ['html'],
passWithNoTests: true,
moduleNameMapper: {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/src/app/__mocks__/fileMock.js',
},
};
// apps/client/src/app/__mocks__/fileMock.js
module.exports = 'test-file-stub';
No worries, we'll make sure testing works well.
@jaysoo Thank you very much!
Thank you! I can’t wait to use Nx for my Ionic projects. 😁
I've opened a PR, but there is one thing I want to potentially tackle before it goes out.
+1
Just wanted to link the PR to this issue for easier tracking #1964
https://github.com/nrwl/nx/pull/1964 has been merged! Thank you @jaysoo !
Is anyone able to get v8.10.1 to work? It keeps saying it can't find the module.
@stramel Unfortunately, not yet.
I could load SVGs when I commented out issuer from @nrwl/react/plugins/webpack.js

Current work around for Nx v8.10 + Ionic/React.
webpack.config.jsconst getWebpackConfig = require('@nrwl/react/plugins/webpack');
function getCustomWebpackConfig(webpackConfig) {
const config = getWebpackConfig(webpackConfig);
// SVG fix
delete config.module.rules.find(rule => rule.test.test('.svg')).issuer;
// // TS v3.7 support
// const babelRuleOptions = config.module.rules.find(r => r.loader === 'babel-loader').options;
// babelRuleOptions.plugins.push('@babel/plugin-proposal-optional-chaining');
// babelRuleOptions.plugins.push('@babel/plugin-proposal-nullish-coalescing-operator');
return config;
}
module.exports = getCustomWebpackConfig;
workspace.json{
"version": 1,
"projects": {
"client": {
"root": "apps/client",
"sourceRoot": "apps/client/src",
"projectType": "application",
"schematics": {},
"architect": {
"build": {
"builder": "@nrwl/web:build",
"options": {
...
"webpackConfig": "./webpack.config.js"
},
apps/client/jest.config.jsmodule.exports = {
name: 'client',
preset: '../../jest.config.js',
transform: {
'^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest',
'^.+\\.[tj]sx?$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
coverageDirectory: '../../coverage/apps/client',
moduleNameMapper: {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/src/app/__mocks__/fileMock.js',
},
modulePathIgnorePatterns: ['<rootDir>/.*/__mocks__'],
};
apps/client/src/app/__mocks__/fileMock.jsmodule.exports = 'test-file-stub';
Hmmm @puku0x I wasn't able to get it working using that webpack config...
@jaysoo Is there documentation around what needs updated or a way to update the apps with the required config? When I run nx serve nextjs-app it gives me this error message:
ModuleParseError: Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>icn</title><path d="M18,13H13v5a1,1,0,0,1-2,0V13H6a1,1,0,0,1,0-2h5V6a1,1,0,0,1,2,0v5h5a1,1,0,0,1,0,2Z"/></svg>
at handleParseError (/project/node_modules/webpack/lib/NormalModule.js:469:19)
at /project/node_modules/webpack/lib/NormalModule.js:503:5
at /project/node_modules/webpack/lib/NormalModule.js:358:12
at /project/node_modules/loader-runner/lib/LoaderRunner.js:373:3
at iterateNormalLoaders (/project/node_modules/loader-runner/lib/LoaderRunner.js:214:10)
at /project/node_modules/loader-runner/lib/LoaderRunner.js:205:4
at /project/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:85:15
at processTicksAndRejections (internal/process/task_queues.js:75:11)
@puku0x I figured out the issue with mine. They applied the change only to the react application with their build chain. Next.js needs these steps:
Add this to your project's tsconfig.json
+ "files": [
+ "../../node_modules/@nrwl/react/typings/image.d.ts"
+ ],
Add this to your project's jest.config.js in the transform object.
+ '^(?!.*\\\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest'
Add this to your project's next.config.js
+ webpack: config => {
+ // Converts SVG files into React components.
+ config.module.rules.push({
+ test: /\.svg$/,
+ issuer: {
+ test: /\.[jt]sx?$/
+ },
+ use: ['@svgr/webpack?-svgo,+titleProp,+ref![path]', 'url-loader']
+ });
+
+ return config
+ }
Install @svgr/webpack and url-loader to your devDependencies.
Everything is working for me now!
So is there a ready solution to the problem? how to add my own loader for svg files?
i want to use
use: [
{
loader: 'svg-sprite-loader',
options: {
symbolId: '[name]'
}
},
'svgo-loader'
]
as loader.
but now i get base64 src string from svg imports
@Krasnopir Does this work for you?
const getWebpackConfig = require('@nrwl/react/plugins/webpack');
function getCustomWebpackConfig(webpackConfig) {
const config = getWebpackConfig(webpackConfig);
// SVG fix
const index = config.module.rules.findIndex(rule => rule.test.test('.svg'));
config.module.rules.splice(index, 1, {
test: /\.svg$/,
//issuer: {
// test: /\.[jt]sx?$/
//},
use: [
{
loader: 'svg-sprite-loader',
options: {
symbolId: '[name]'
}
},
'svgo-loader'
]
});
return config;
}
module.exports = getCustomWebpackConfig;
@Krasnopir Does this work for you?
const getWebpackConfig = require('@nrwl/react/plugins/webpack'); function getCustomWebpackConfig(webpackConfig) { const config = getWebpackConfig(webpackConfig); // SVG fix const index = config.module.rules.findIndex(rule => rule.test.test('.svg')); config.module.rules.splice(index, 1, { test: /\.svg$/, //issuer: { // test: /\.[jt]sx?$/ //}, use: [ { loader: 'svg-sprite-loader', options: { symbolId: '[name]' } }, 'svgo-loader' ] }); return config; } module.exports = getCustomWebpackConfig;
great. it work!!! much thanks!
@puku0x We need to update this for Next.js apps as well since it's managed by a different loader. Should track it separately here #2350.
The issuer is supposed to to prevent SVG imports within CSS files from being processed. Are your imports from .jsx and .tsx files?
I also realized that SVG support was not working from CSS files, not sure if this is the issue people were running into, but Nx should be using oneOf in the webpack rule for SVG so we use the first matched rule.
This PR will allow SVGs to be imported in CSS files. https://github.com/nrwl/nx/pull/2351
Let me know if there are any other issues. The sprites use case isn't officially supported right now, but we could look into it in the future.
@jaysoo I’m importing SVGs from not only .tsx but also .css because I’m using Ionic. #2351 will be a great help for me. Thank you!
Sounds good. We'll have this in the next release.
Closing this issue. If there are further use cases that aren't addressed please open a new issue. :)
Now Ionic React on Nx works out of the box!
/**
app.tsx
After cloning master,
$ yarn create-playground
$ cd tmp/nx/proj
$ yarn nx g @nrwl/react:app
$ yarn add @ionic/react
*/
import React from 'react';
import {
IonApp,
IonContent,
IonHeader,
IonPage,
IonTitle,
IonToolbar
} from '@ionic/react';
/* Core CSS required for Ionic components to work properly */
import '@ionic/react/css/core.css';
/* Basic CSS for apps built with Ionic */
import '@ionic/react/css/normalize.css';
import '@ionic/react/css/structure.css';
import '@ionic/react/css/typography.css';
/* Optional CSS utils that can be commented out */
import '@ionic/react/css/padding.css';
import '@ionic/react/css/float-elements.css';
import '@ionic/react/css/text-alignment.css';
import '@ionic/react/css/text-transformation.css';
import '@ionic/react/css/flex-utils.css';
import '@ionic/react/css/display.css';
export const App = () => {
return (
<IonApp>
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Title</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent>
<p>Welcome to web!</p>
</IonContent>
</IonPage>
</IonApp>
);
};
export default App;
...except testing 😂
$ yarn test
yarn run v1.19.0
$ nx test web
FAIL apps/web/src/app/app.spec.tsx
● Test suite failed to run
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
/Users/puku0x/GitHub/nx/tmp/nx/proj/node_modules/ionicons/dist/ionicons/svg/ios-add.svg:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M368.5 240H272v-96.5c0-8.8-7.2-16-16-16s-16 7.2-16 16V240h-96.5c-8.8 0-16 7.2-16 16 0 4.4 1.8 8.4 4.7 11.3 2.9 2.9 6.9 4.7 11.3 4.7H240v96.5c0 4.4 1.8 8.4 4.7 11.3 2.9 2.9 6.9 4.7 11.3 4.7 8.8 0 16-7.2 16-16V272h96.5c8.8 0 16-7.2 16-16s-7.2-16-16-16z"/></svg>
^
SyntaxError: Unexpected token <
at ScriptTransformer._transformAndBuildScript (../../node_modules/@jest/transform/build/ScriptTransformer.js:537:17)
at ScriptTransformer.transform (../../node_modules/@jest/transform/build/ScriptTransformer.js:579:25)
at Object.<anonymous> (../../node_modules/ionicons/icons/imports/add.js:2:8)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 2.826s
Ran all test suites.
error Command failed with exit code 1.
@puku0x in order to get Ionic to work with the latest release, I still had to make webpack.config.js modifications that you posted. Also, were you able to get passed the linting error from using the require in the Webpack config? error Require statement not part of import statement @typescript-eslint/no-var-requires
@devinshoemaker Sorry for confusing you. I tested above example on the developing version of Nx which has not been released on npm yet. Therefore, you still need the webpack config for current version of Nx (v8.11.2). I think "Nx + Ionic React" should work in next release!
@devinshoemaker Talking about the linting error in webpack.config.js, I faced the same error but I ignored it and used require because '@nrwl/react/plugins/webpack' was not an ES module.
Most helpful comment
No worries, we'll make sure testing works well.