Reputation: 101
I created a project with create-react-app using Typescript and latter I was asked to add next.js to it, what happend was that it broked some svgs across the application. To fix that I added this package: https://www.npmjs.com/package/next-images
on my next.config.js I ended up with this configuration:
module.exports = withImages({
webpack: config => {
return config
},
})
with this configuration I can now see my images across the application, but just the public ones, if I try to add a svg like a React component following this approach:
import { ReactComponent as IconPlus } from 'assets/icons/icon-plus.svg'
I end up with this error:
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
I tried to add react-svg-inline as I saw in some other posts, so I ended up adding .babelrc for Next.js like this:
.babelrc
{
"plugins": [
"inline-react-svg"
]
}
After changing this I changed my svg import to just:
import IconPlus from 'assets/icons/icon-plus.svg'
and used it like
after adding .babelrc and the inline-react-svg, I get this error:
Syntax error: Support for the experimental syntax 'jsx' isn't currently enabled (5:10):
Any help on this, Am I doing something wrong on the babel configuration, thanks :)
Upvotes: 10
Views: 11898
Reputation: 636
you dont need to add any library, if you want, you can create a new component with that svg you have. Imagine you have your source folder organized like that:
-component
|--SvgIconPlus
|---index.tsx
-page
|-index.tsx
1- Just copy the svg file inside the return component
export default function SvgIconPlusComponent() {
return (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12.27 12" xmlns:v="https://vecta.io/nano"><path d="M11.17 4.38L6.88 8.99V0h-1.5v8.99L1.1 4.38 0 5.4 6.13 12l6.14-6.6-1.1-1.02z" fill="#000"/></svg>
);
}
2- Import it in your page index.tsx
import SvgIconPlusComponent from '../components/SvgIconPlus'
export default function MyPage(){
return(<div><SvgIconPlusComponent /></div>);
}
Upvotes: -2
Reputation: 141
Change .babelrc
to be:
{
"presets": ["next/babel"],
"plugins": ["inline-react-svg"]
}
Import your .svg
files relative to their location:
import IconPlus from "../assets/icons/icon-plus.svg";
You can read more about import absolute paths here.
If you just want to create React components from .svg
, you don't have to use next-images
.
Here is a working example https://github.com/vercel/next.js/tree/canary/examples/svg-components.
Upvotes: 3