Tips & Tricks (Diperbarui: 2/6/2026)

Manipulasi SVG dengan Claude Code: panduan praktis

Pelajari SVG dengan Claude Code: viewBox, ikon aksesibel, currentColor, animasi, optimasi SVGO, dan jebakan keamanan.

Manipulasi SVG dengan Claude Code: panduan praktis

Tentukan aturan sebelum membuat SVG

SVG cocok untuk ikon, logo, diagram, dan visualisasi data kecil. Format ini tetap tajam saat diperbesar dan dapat mewarisi warna dari CSS. Claude Code bisa membaca repository, mengedit file, dan menjalankan pengecekan, sehingga cocok untuk mengubah SVG mentah menjadi komponen UI yang rapi.

Masalah muncul ketika prompt terlalu umum. “Buatkan ikon SVG” bisa menghasilkan gambar yang terlihat benar, tetapi tidak punya viewBox, memakai warna hard-coded, tidak punya nama aksesibel, mengabaikan reduced motion, atau rusak setelah dioptimalkan. Masa pernah menemukan ini saat menguji UI kecil untuk ClaudeCodeLab: ikon terlihat bagus, tetapi harus diedit manual ketika dipakai di tombol dengan teks, tombol hanya ikon, dan mode gelap.

Panduan ini memberi alur yang lebih aman: tetapkan viewBox, gunakan currentColor, bedakan ikon dekoratif dan ikon bermakna, tambahkan animasi ringan, optimalkan dengan SVGO, lalu cek layout dan keamanan. Rujukan resmi yang dipakai adalah MDN <svg>, MDN viewBox, MDN ARIA img role, MDN aria-hidden, SVGO docs, dan Claude Code docs.

Alur kerja yang aman

Pekerjaan SVG bukan hanya menggambar. Di aplikasi nyata, SVG menyentuh design system, aksesibilitas, performa, keamanan, dan review kode.

flowchart LR
  A["Tentukan tujuan"] --> B["Kunci viewBox"]
  B --> C["Gunakan currentColor"]
  C --> D["Pilih aria-label atau aria-hidden"]
  D --> E["Pasang di HTML atau React"]
  E --> F["Optimalkan dengan SVGO"]
  F --> G["Review layout dan keamanan"]

Prompt yang lebih baik adalah: “Buat komponen ikon SVG dengan viewBox="0 0 24 24", stroke="currentColor", ikon dekoratif memakai aria-hidden, ikon mandiri yang bermakna memakai role="img" dan title, lalu tambahkan konfigurasi SVGO yang tidak menghapus viewBox.”

Inline SVG dan viewBox

Inline SVG berarti markup <svg> ditulis langsung di HTML atau JSX, bukan dimuat lewat img. Cara ini berguna saat ikon harus mengikuti warna tema, hover state, props React, atau animasi ringan.

viewBox adalah sistem koordinat internal SVG. MDN menjelaskannya sebagai empat angka: min-x min-y width height. Secara praktis, viewBox="0 0 24 24" berarti ikon digambar di grid 24 kali 24, meskipun nanti ditampilkan pada 16px, 24px, atau 48px.

<button class="icon-button" type="button" aria-label="Cari">
  <svg
    class="icon"
    viewBox="0 0 24 24"
    width="24"
    height="24"
    fill="none"
    stroke="currentColor"
    stroke-width="2"
    stroke-linecap="round"
    stroke-linejoin="round"
    aria-hidden="true"
    focusable="false"
  >
    <circle cx="11" cy="11" r="7" />
    <path d="M20 20l-4.5-4.5" />
  </svg>
</button>

Button sudah punya nama aksesibel, jadi SVG di dalamnya dekoratif. Jika button hanya menampilkan ikon, nama harus ada di button. Jika SVG berdiri sendiri sebagai gambar bermakna, SVG perlu diberi nama.

Theme dengan currentColor dan CSS variables

Warna tetap di dalam SVG membuat maintenance sulit. Jika path berisi fill="#111827", Claude Code harus mengedit SVG setiap kali theme berubah. Untuk ikon UI, lebih aman membuat SVG mewarisi warna CSS.

:root {
  --color-text: #172033;
  --color-muted: #667085;
  --color-accent: #0f766e;
  --color-danger: #b42318;
}

[data-theme="dark"] {
  --color-text: #eef2f7;
  --color-muted: #a9b4c3;
  --color-accent: #2dd4bf;
  --color-danger: #f97066;
}

.icon {
  color: var(--icon-color, var(--color-text));
  display: inline-block;
  inline-size: 1.25rem;
  block-size: 1.25rem;
  flex: 0 0 auto;
}

.icon-button {
  color: var(--color-muted);
}

.icon-button:hover {
  color: var(--color-accent);
}

.icon-button[data-variant="danger"] {
  --icon-color: var(--color-danger);
}
<button class="icon-button" type="button" aria-label="Hapus" data-variant="danger">
  <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true">
    <path d="M4 7h16" />
    <path d="M10 11v6" />
    <path d="M14 11v6" />
    <path d="M6 7l1 14h10l1-14" />
    <path d="M9 7V4h6v3" />
  </svg>
</button>

Setelah refactor, minta Claude Code menjalankan rg "fill=\"#|stroke=\"#" di folder komponen dan assets. Logo boleh menjadi pengecualian, tetapi ikon UI umum sebaiknya memakai currentColor.

Komponen React yang aksesibel

SVG yang punya makna perlu nama aksesibel. SVG dekoratif sebaiknya disembunyikan dari accessibility tree. MDN merekomendasikan role="img" dan label untuk SVG yang menjadi gambar, sedangkan aria-hidden="true" sesuai untuk konten dekoratif yang tidak interaktif.

import { useId } from "react";

type IconName = "search" | "check" | "close";

const paths: Record<IconName, string> = {
  search: "M10.5 18a7.5 7.5 0 1 1 5.3-12.8 7.5 7.5 0 0 1-5.3 12.8Zm5.3-2.2L21 21",
  check: "M5 12.5l4.5 4.5L19 7",
  close: "M6 6l12 12M18 6L6 18",
};

type SvgIconProps = {
  name: IconName;
  title?: string;
  decorative?: boolean;
  size?: number;
  className?: string;
};

export function SvgIcon({
  name,
  title,
  decorative = false,
  size = 24,
  className,
}: SvgIconProps) {
  const titleId = useId();
  const isMeaningful = !decorative && Boolean(title);

  return (
    <svg
      className={className}
      width={size}
      height={size}
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      strokeWidth={2}
      strokeLinecap="round"
      strokeLinejoin="round"
      role={isMeaningful ? "img" : undefined}
      aria-labelledby={isMeaningful ? titleId : undefined}
      aria-hidden={decorative ? true : undefined}
      focusable="false"
    >
      {isMeaningful ? <title id={titleId}>{title}</title> : null}
      <path d={paths[name]} />
    </svg>
  );
}
<button type="button">
  <SvgIcon name="check" decorative />
  Simpan
</button>

<SvgIcon name="search" title="Cari" />

Contoh pertama memiliki teks button, jadi ikonnya dekoratif. Contoh kedua membuat ikon berdiri sendiri, jadi title diperlukan. Jangan menaruh aria-hidden="true" pada elemen yang bisa menerima fokus.

Animasi ringan

Animasi SVG cocok untuk loading, success state, atau penekanan kecil. Ukuran elemen harus stabil dan prefers-reduced-motion perlu dihormati.

<svg class="spinner" viewBox="0 0 48 48" width="48" height="48" role="img" aria-label="Memuat">
  <circle class="spinner-track" cx="24" cy="24" r="20" />
  <circle class="spinner-head" cx="24" cy="24" r="20" />
</svg>
.spinner {
  color: #0f766e;
  animation: spin 900ms linear infinite;
}

.spinner-track,
.spinner-head {
  fill: none;
  stroke-width: 4;
}

.spinner-track {
  stroke: #d0d5dd;
}

.spinner-head {
  stroke: currentColor;
  stroke-linecap: round;
  stroke-dasharray: 80 45;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .spinner {
    animation: none;
  }
}

Untuk pola gerak yang lebih luas, baca juga Claude Code CSS animation advanced. SVG sebaiknya mendefinisikan bentuk, sedangkan CSS mengatur state dan motion.

Membuat chart SVG kecil

SVG juga bisa dipakai untuk chart kecil. Jika label berasal dari data luar, escape dulu sebelum masuk ke <text>.

type BarDatum = {
  label: string;
  value: number;
};

function escapeXml(value: string): string {
  return value.replace(/[<>&"']/g, (char) => {
    const entities: Record<string, string> = {
      "<": "&lt;",
      ">": "&gt;",
      "&": "&amp;",
      '"': "&quot;",
      "'": "&apos;",
    };
    return entities[char];
  });
}

export function createMiniBarChart(data: BarDatum[]): string {
  const width = 420;
  const height = 180;
  const padding = 32;
  const gap = 12;
  const maxValue = Math.max(...data.map((item) => item.value), 1);
  const barWidth = (width - padding * 2 - gap * (data.length - 1)) / data.length;

  const bars = data
    .map((item, index) => {
      const barHeight = (item.value / maxValue) * 100;
      const x = padding + index * (barWidth + gap);
      const y = height - padding - barHeight;

      return `
        <rect x="${x}" y="${y}" width="${barWidth}" height="${barHeight}" rx="6" fill="currentColor" />
        <text x="${x + barWidth / 2}" y="${height - 10}" text-anchor="middle" font-size="12">
          ${escapeXml(item.label)}
        </text>`;
    })
    .join("");

  return `<svg viewBox="0 0 ${width} ${height}" role="img" aria-label="Jumlah pertanyaan bulanan" xmlns="http://www.w3.org/2000/svg">
    <g color="#0f766e">${bars}</g>
  </svg>`;
}

Pendekatan ini cocok untuk dashboard kecil, ilustrasi artikel, dan bukti sosial di landing page. Jika butuh axis, legend, tooltip, zoom, atau data besar, gunakan chart library.

Optimasi dengan SVGO

SVG dari tool desain biasanya membawa metadata, atribut editor, dan angka terlalu panjang. SVGO membersihkannya. Mulai dari konfigurasi konservatif lalu review diff.

// svgo.config.mjs
export default {
  multipass: true,
  plugins: [
    {
      name: "preset-default",
      params: {
        overrides: {
          cleanupIds: false
        }
      }
    },
    "removeDimensions",
    {
      name: "removeAttrs",
      params: {
        attrs: ["data-name"]
      }
    }
  ]
};
{
  "scripts": {
    "svg:optimize": "svgo --config svgo.config.mjs --folder src/assets/icons"
  },
  "devDependencies": {
    "svgo": "^4.0.0"
  }
}

Dokumentasi SVGO menjelaskan preset-default, removeDimensions, dan plugin lain. Hati-hati dengan removeViewBox: dokumentasi memperingatkan bahwa plugin itu dapat membuat SVG tidak bisa mengisi container dan bisa terpotong.

Use case dan jebakan

Use case paling umum adalah sistem ikon produk, diagram untuk artikel teknis, visual di dekat pricing atau tombol pembelian, serta chart kecil untuk completion rate, CTA click, atau jumlah inquiry. Dalam halaman monetisasi, SVG harus membantu pembaca memahami nilai, bukan mengganggu CTA.

KesalahanDampakPerbaikan
Menghapus viewBoxIkon terpotong atau tidak responsifPertahankan di SVGO dan review diff
Warna fixedDark mode dan hover gagalGunakan currentColor
Menyembunyikan ikon bermaknaScreen reader kehilangan aksiBeri nama pada button atau SVG
Membacakan ikon dekoratifLabel menjadi berulangGunakan aria-hidden="true"
Inline SVG upload userRisiko script atau event handlerInline hanya SVG tepercaya
Mengabaikan reduced motionGerakan mengganggu sebagian userGunakan prefers-reduced-motion

MDN mendokumentasikan elemen SVG <script>, jadi jangan anggap SVG upload user sebagai teks gambar yang aman. Claude Code dapat membantu review diff, tetapi batasi folder target dan baca perubahan. Untuk izin dan command, lihat juga Claude Code security.

Prompt yang bisa dipakai ulang

Buat sistem ikon SVG untuk repository ini.
Syarat:
- Pertahankan viewBox="0 0 24 24"
- Gunakan currentColor untuk fill atau stroke
- Sembunyikan ikon dekoratif dengan aria-hidden=true
- Gunakan role=img dan title untuk ikon mandiri yang bermakna
- Tambahkan loading SVG yang menghormati prefers-reduced-motion
- Tambahkan konfigurasi SVGO yang tidak menghapus viewBox
- Laporkan risiko, file yang berubah, dan command verifikasi

Untuk tahap berikutnya, hubungkan dengan optimasi performa Claude Code, karena jumlah ikon, diagram, dan animasi tetap memengaruhi berat halaman dan rendering.

CTA dan hasil uji

Jika ingin menjadikannya setup reusable, lihat produk dan template ClaudeCodeLab atau bawa repository nyata ke training dan konsultasi Claude Code. SVG adalah target awal yang bagus karena scope kecil, tetapi menyentuh design, aksesibilitas, performa, dan disiplin review.

Di UI uji Masa, memindahkan warna fixed ke currentColor membuat ikon yang sama bisa dipakai di light mode, dark mode, dan destructive button. Bug yang benar-benar muncul adalah aksesibilitas: tombol search yang hanya berisi ikon kehilangan nama ketika aria-hidden diterapkan secara mekanis ke semua ikon. Aturan finalnya sederhana: beri nama pada button, dan sembunyikan hanya ikon dekoratif.

#Claude Code #SVG #ikon #animation #optimization
Gratis

PDF gratis: cheatsheet Claude Code

Masukkan email dan unduh satu halaman berisi command, kebiasaan review, dan workflow aman.

Kami menjaga datamu dan tidak mengirim spam.

Masa

Tentang penulis

Masa

Engineer yang berfokus pada workflow Claude Code praktis dan adopsi tim.