'Import .svg and resize .svg use styled-components in next.js
I am currently trying import .svg into next.js project but I failed.
I tried import .svg same way as in react project, that I created typing.d.ts and import svg like component. But it doesn't work.
declare module '*.svg' {
import React from 'react';
const src: string;
export const ReactComponent: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
export default src;
}
Import svg example
- I using next.js - 12.1 and styled-components - 5.3.3
- example-import-svg
What I need?
- Import
.svg
file and change its width and height.
Has anyone had the same problem? Or did anyone manage to solve it?
Thank you
Solution 1:[1]
Maybe a solution.
- Default option in next.js for
removeViewBox
istrue
. If you change in .svgheight
orwidth
the view-box from.svg
will be rest to default value. - If you use in your
next.config.js
webpack and setremoveViewBox
tofalse
.svg resize start work.
A working example: stackblitz-resize-svg-next.js
webpack(config) {
config.module.rules.push({
loader: '@svgr/webpack',
options: {
prettier: false,
svgo: true,
svgoConfig: {
plugins: [
{
name: 'preset-default',
params: {
overrides: { removeViewBox: false },
},
},
],
},
titleProp: true,
},
test: /\.svg$/,
});
return config;
},
If you have in .babelrc
set "inline-react-svg"
this solution will not work.
Solution 2:[2]
Another approach I've used, leverages svgo-loader
:
// Asset handling
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
// SVG handler, inlines everything under 200KB
config.module.rules.push({
test: /\.svg$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 200 * 1024
}
},
use: 'svgo-loader'
});
return config;
},
Solution 3:[3]
I am using like that.
1- I created a Component with the SVG code that receives as a parameter width, height, or none of them
2- If it has none of them, gets the svg default width and value, else it will return the svg with its new width or height value, according to the one given
3- The default value is added to the viewBox attribute
As you can see the code below:
type SVGDoubleArrowIconProps = {
newWidth?: number;
newHeight?: number;
};
export default function SVGDoubleArrowIcon({ newWidth, newHeight }: SVGDoubleArrowIconProps) {
const defaultDimensions = { width: 50, height: 50 };
let finalDimensions = { width: 0, height: 0 };
if (!newWidth && !newHeight) {
finalDimensions.width = defaultDimensions.width;
finalDimensions.height = defaultDimensions.height;
} else if (newWidth) {
finalDimensions.width = newWidth;
const ratio = newWidth / defaultDimensions.width;
finalDimensions.height = ratio * defaultDimensions.height;
} else if (newHeight) {
finalDimensions.height = newHeight;
const ratio = newHeight / defaultDimensions.height;
finalDimensions.width = ratio * defaultDimensions.width;
}
return (
<svg
width={finalDimensions.width}
height={finalDimensions.height}
viewBox={`0 0 ${defaultDimensions.width} ${defaultDimensions.height}`}
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M56.4411 24.9827C56.4489 24.9729 56.4481 24.9588
56.4393 24.9499L33.6545 1.93291C32.8718 1.14228 31.5944 1.14228 30.8117
1.93291L26.3926 6.3971C25.6212 7.17637 25.621 8.43145 26.3923
9.21088L40.6236 23.5929C41.3948 24.3723 41.3947 25.6274 40.6233
26.4067L26.3922 40.7827C25.6209 41.5618 25.6206 42.8166 26.3915
43.5961L30.8115 48.0654C31.5942 48.8567 32.8722 48.8569 33.6551
48.0658L56.4404 25.042C56.4484 25.0339 56.4484 25.021 56.4404
25.0129C56.433 25.0055 56.4324 24.9938 56.4389 24.9856L56.4411 24.9827Z"
fill="#01FFA9"
stroke="#0E0E0E"
strokeWidth="2"
strokeMiterlimit="10"
/>
<path
d="M32.4455 24.9817C32.4544 24.9727 32.4544 24.9582
32.4455 24.9492L9.65446 1.93251C8.87177 1.14207 7.59451 1.14216 6.81194
1.93271L2.39284 6.39682C1.62132 7.1762 1.62132 8.4315 2.39284
9.21088L16.6295 23.5926C17.4012 24.3721 17.401 25.6276 16.6293
26.4069L2.39274 40.7827C1.62122 41.5618 1.6208 42.8168 2.3918
43.5964L6.81175 48.0656C7.59429 48.8568 8.87221 48.8571 9.65513
48.0662L32.4462 25.043C32.4544 25.0347 32.4537 25.0211 32.4445
25.0137C32.4354 25.0063 32.4347 24.9927 32.4429 24.9843L32.4455 24.9817Z"
fill="#01FFA9"
stroke="#0E0E0E"
strokeWidth="2"
strokeMiterlimit="10"
/>
</svg>
);
}
That way i can import it in any component or page and use it in:
1- New widths:
import SVGDoubleArrowIcon from '../components/SVGDoubleArrowIcon'
export default function MyPage(){
return(<div><SVGDoubleArrowIcon width={300} /></div>);
}
2- New heights:
import SVGDoubleArrowIcon from '../components/SVGDoubleArrowIcon'
export default function MyPage(){
return(<div><SVGDoubleArrowIcon height={300} /></div>);
}
3- Or default width and height
import SVGDoubleArrowIcon from '../components/SVGDoubleArrowIcon'
export default function MyPage(){
return(<div><SVGDoubleArrowIcon /></div>);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | mikekubn |
Solution 2 | serraosays |
Solution 3 | Germano |