🐹

Next.js で SVG をコンポーネントっぽくインラインで読み込みたい

2021/03/27に公開

SVG 用のコンポーネントとか作らずに、SVG をそのまま読み込んで以下のように書きたい。

logo.tsx
import { FC } from 'react'
import styles from 'src/styles/logo.module.scss'
import Icon from 'src/images/icon.svg'

const Logo: FC = () => (
  <div>
    <Icon className={styles.logo} />
  </div>
)

export default Logo

babel-plugin-inline-react-svg を使う

いろいろ方法はあるみたいなのですが、公式に使用例があったので babel-plugin-inline-react-svg を使ってみます。

yarn add -D babel-plugin-inline-react-svg

babel.config.js に以下を追加。

babel.config.js
module.exports = {
   presets: ['next/babel'],
+  plugins: ['inline-react-svg'],
}

以上で完了です🙆‍♂️

絶対パスで読み込みたい

これで読み込めるようにはなったのですが、相対パスで書くのしんどい。絶対パスで読み込みたい。
ので babel-plugin-module-resolver をインストール。

yarn add -D babel-plugin-module-resolver

babel.config.js を編集。

babel.config.js
module.exports = {
   presets: ['next/babel'],
-  plugins: ['inline-react-svg'],
+  plugins: [
+    [
+      'module-resolver',
+      {
+        root: ['.'],
+      },
+    ],
+    'inline-react-svg',
+  ],
}

tsconfig.json には baseUrl を設定。

tsconfig.json
{
  "compilerOptions": {
    ...
    "baseUrl": ".",
  },
  ...
}

以上で絶対パスで読み込めるようになりました🙆‍♂️

ちなみにエイリアスも使えました。

babel.config.js
module.exports = {
  presets: ['next/babel'],
  plugins: [
+    [
+      'module-resolver',
+      {
+        alias: {
+          @svg: './src/svg',
+        },
+      },
+    ],
     'inline-react-svg',
  ],
}
tsconfig.json
{
   "compilerOptions": {
     ...
     "baseUrl": ".",
+    "paths": {
+      "@svg*": [
+        "src/svg*"
+      ]
+    }
   },
   ...
}

こんな感じです。
なにかもっと良い方法があったら教えて下さい🙇‍♂️

Discussion