Cara Import SVG di NextJS
Permasalahan
Sebenarnya, untuk import SVG,JPG, Webp dan extension image lain, secara default sudah didukung di NextJS. Misalnya saja
const Member = () => {
return (
<>
<img
src="/assets/img/team-1.png"
alt="Icon Team 1"
className="h-8 w-8 -mr-2"
/>
</>
);
};
Permasalahan mulai muncul saat saya ingin mencoba untuk melakukan custom SVG yang saya miliki. Mulai dari merubah warna misalnya seperti yang telah aku jabarkan mengenai alasan menggunakan ReactComponent untuk SVG.
Sehingga saya memerlukan SVG sebagai sebuah ReactComponent. Bukan sebagai sebuah element biasa.
Solusi
Ada 3 solusi yang saat ini saya ketahui. Namun saya hanya mencoba 2 solusi dari 3 tersebut.
Pertama menggunakan SVGR.
Sebuah Tools yang mengizinkan kita untuk melakukan import SVG sebagai React Component. Caranya adalah dengan memasang dependencies @svgr/webpack
pada NextJS kita lalu merubah setup di next.config.js . Caranya bisa membaca di dokumentasi NextJS , atau memasangnya seperti ini berdasarkan tulisan ini
module.exports = {
webpack(config) {
config.module.rules.push({
test: /\.svg$/,
use: ["@svgr/webpack"]
});
return config;
}
};
Lalu, kita bisa menuliskannya seperti ini
mport React from 'react';
import Dog from "./Dog.svg";
export const DogComponent = () => (
<div>
<h1>Dogs are nice</h1>
<Dog classNames="h-4 w-4" />
</div>
);
Benar, caranya berbeda dengan cara import di CRA.
Kedua, menggunakan babel-plugin-react-svg
Salh satu plugin dari Airbnb dan ini yang sering aku gunakan untuk proyek-proyekku karena cukup merubah / menambah di babelnya. Dokumentasi bisa dilihat disini.
- Install dengan menggunakan perintah
npm install --save-dev babel-plugin-inline-react-svg
- Buaf file baru di root folder proyek dengan nama .babelrc dan isikan dengan kode dibawah
{
"presets": ["next/babel"],
"plugins": ["inline-react-svg"]
}
Sehingga saat menuliskan kode nya bisa menjadi seperti ini
import React from 'react';
import Dog from "./Dog.svg";
export const DogComponent = () => (
<div>
<h1>Dogs are nice</h1>
<Dog classNames="h-4 w-4" />
</div>
);
Ketiga, dengan mengcopy file SVG tersebut untuk menjadi inline atau component baru. Misalnya kamu memiliki SVG seperti ini :
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="4" cy="4" r="4" fill="#FF3333"/>
</svg>
Lalu kamu tinggal membuat component baru dari file tersebut menjadi
import React from 'react';
export const NotifIcon = () => (
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="4" cy="4" r="4" fill="#FF3333"/>
</svg>
)
atau menjadi inline
export const Notif = () => (
<div className="flex items-center w-full">
<div className="bg-blue-200 w-8 h-8 mr-4 rounded flex items-center justify-center">
<svg
width="8"
height="8"
viewBox="0 0 8 8"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="4" cy="4" r="4" fill="#FF3333" />
</svg>
</div>
<h5 className="text-2xl font-semibold text-gray-100">Event Calendar</h5>
</div>
);
Saya sendiri memutuskan untuk menggunakan babel dan menjadikannya sebagai React Component karena bisa melakukan custom langsung pada component SVG tersebut seperti merubah warna, ukuran serta mungkin kedepan untuk kebutuhan animasi.