Qadam Roadmap
проектplans/archived/2026-03-28-integrated/2026-03-18-svg-icons.md

Custom SVG Icons via SVGR — Implementation Plan

Обновлён 1 апр. 2026 г., 12:41 · 0 комментариев

Custom SVG Icons via SVGR — Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Set up SVGR so SVG files from Figma can be imported as React components with currentColor and flexible sizing.

Architecture: @svgr/webpack transforms .svg files into React components at build time. Turbopack config handles dev, webpack config handles production. Icons live in apps/web/src/shared/icons/ with a barrel re-export.

Tech Stack: Next.js 16, @svgr/webpack@^8, TypeScript, Tailwind CSS 4

Spec: docs/superpowers/specs/2026-03-18-svg-icons-design.md


Task 1: Install @svgr/webpack

Files:

  • Modify: apps/web/package.json

  • Step 1: Install the dependency

cd apps/web && pnpm add -D @svgr/webpack@^8
  • Step 2: Verify installation
cd apps/web && pnpm list @svgr/webpack

Expected: shows @svgr/webpack 8.x.x

  • Step 3: Commit
git add apps/web/package.json pnpm-lock.yaml
git commit -m "chore: add @svgr/webpack dependency"

Task 2: Configure Next.js for SVGR (Turbopack + Webpack)

Files:

  • Modify: apps/web/next.config.ts

  • Step 1: Add Turbopack and Webpack SVG rules to next.config.ts

Replace the current nextConfig object with:

import type { NextConfig } from 'next';
import { resolve } from 'path';
import createNextIntlPlugin from 'next-intl/plugin';

const withNextIntl = createNextIntlPlugin('./src/shared/i18n/request.ts');

const nextConfig: NextConfig = {
  output: 'standalone',
  outputFileTracingRoot: resolve(__dirname, '../../'),
  reactStrictMode: true,
  transpilePackages: ['@repo/shared', '@repo/ui'],
  reactCompiler: true,
  turbopack: {
    rules: {
      '*.svg': {
        loaders: [
          {
            loader: '@svgr/webpack',
            options: {
              svgoConfig: {
                plugins: [
                  {
                    name: 'preset-default',
                    params: {
                      overrides: {
                        removeViewBox: false,
                      },
                    },
                  },
                  {
                    name: 'convertColors',
                    params: {
                      currentColor: true,
                    },
                  },
                ],
              },
            },
          },
        ],
        as: '*.js',
      },
    },
  },
  webpack(config) {
    // Remove Next.js built-in SVG handling to avoid conflicts
    const fileLoaderRule = config.module.rules.find(
      (rule: { test?: RegExp }) => rule.test?.test?.('.svg'),
    );
    if (fileLoaderRule) {
      fileLoaderRule.exclude = /\.svg$/;
    }

    config.module.rules.push({
      test: /\.svg$/,
      use: [
        {
          loader: '@svgr/webpack',
          options: {
            svgoConfig: {
              plugins: [
                {
                  name: 'preset-default',
                  params: {
                    overrides: {
                      removeViewBox: false,
                    },
                  },
                },
                {
                  name: 'convertColors',
                  params: {
                    currentColor: true,
                  },
                },
              ],
            },
          },
        },
      ],
    });
    return config;
  },
  ...(process.env.NODE_ENV === 'development' && {
    async rewrites() {
      return [
        {
          source: '/api/v1/:path*',
          destination: `${process.env.API_URL || 'http://localhost:5001'}/api/v1/:path*`,
        },
      ];
    },
  }),
};

export default withNextIntl(nextConfig);
  • Step 2: Commit
git add apps/web/next.config.ts
git commit -m "feat: configure SVGR for Turbopack and Webpack"

Task 3: Add TypeScript declaration for SVG imports

Files:

  • Create: apps/web/svg.d.ts

  • Step 1: Create svg.d.ts at project root (alongside next-env.d.ts)

declare module '*.svg' {
  import { FC, SVGProps } from 'react';
  const component: FC<SVGProps<SVGSVGElement>>;
  export default component;
}
  • Step 2: Verify tsconfig.json includes it

The existing include pattern "**/*.ts" already covers svg.d.ts at the project root. No changes needed.

Run:

cd apps/web && pnpm check-types

Expected: no errors

  • Step 3: Commit
git add apps/web/svg.d.ts
git commit -m "feat: add TypeScript declaration for SVG imports"

Task 4: Create icons directory and migrate existing SVG

Files:

  • Create: apps/web/src/shared/icons/index.ts

  • Move: apps/web/public/icon/map-pin.svgapps/web/src/shared/icons/map-pin.svg

  • Delete: apps/web/public/icon/ (directory)

  • Step 1: Create the icons directory

mkdir -p apps/web/src/shared/icons
  • Step 2: Move the existing map-pin.svg
mv apps/web/public/icon/map-pin.svg apps/web/src/shared/icons/map-pin.svg
  • Step 3: Delete the empty public/icon/ directory
rm -r apps/web/public/icon
  • Step 4: Create index.ts barrel file
export { default as MapPinIcon } from './map-pin.svg';
  • Step 5: Commit

Note: apps/web/public/icon/ was untracked by git, so deleting it requires no git operation. Only the new files need to be staged.

git add apps/web/src/shared/icons/
git commit -m "feat: create shared/icons directory, migrate map-pin.svg"

Task 5: Verify the setup works end-to-end

Files:

  • No new files — uses existing setup

  • Step 1: Run type check

cd apps/web && pnpm check-types

Expected: no errors

  • Step 2: Run dev server and verify SVG import works
cd apps/web && pnpm dev

In browser devtools or by temporarily adding to any page component:

import { MapPinIcon } from '@/shared/icons';

// Inside the component JSX:
<MapPinIcon className="w-6 h-6 text-primary-500" />

Expected: the map pin icon renders, colored in primary-500, sized at 24x24px.

  • Step 3: Run production build
cd apps/web && pnpm build

Expected: build succeeds without errors

  • Step 4: Clean up test usage (remove temporary import if added)

  • Step 5: Commit any remaining changes

git add -A && git commit -m "feat: verify SVG icons setup works"