SVG sang JSX
Dán một file SVG vào và nhận lại component React. Thuộc tính HTML được đổi sang dạng JSX tương ứng, chuỗi style inline thành object style, và mã được thụt lề sẵn để dán thẳng vào file .tsx.
Mọi thứ chạy ngay trên máy bạn; không có gì được tải lên.
Vì sao không dán thẳng SVG vào React được
JSX không phải HTML. Copy nguyên một file SVG xuất ra rồi dán vào component sẽ lỗi hoặc cảnh báo vì:
classphải thànhclassName,forphải thànhhtmlFor.- Thuộc tính SVG có gạch nối (
stroke-width,stop-color,clip-rule) phải chuyển sang camelCase. - Thuộc tính có namespace (
xlink:href,xml:space) không phải định danh JSX hợp lệ. style="fill:red"phải là object:style={{ fill: "red" }}.- Ký tự
{và}trong text bị hiểu là biểu thức JSX.
Công cụ này xử lý cả năm trường hợp, và giữ nguyên data-* cùng aria-* vì React vẫn dùng chúng ở dạng gạch nối.
Các bước
- Dán mã SVG vào bên trái, hoặc bấm Tải file. Khi tải file, tên component cũng được điền theo tên file (
arrow-left.svg→ArrowLeft). - Chọn dạng kết quả: Component (.tsx), Component (.jsx) hoặc JSX thuần.
- Bật/tắt các tùy chọn bên dưới.
- Sao chép, hoặc Tải xuống thành
<Tên>.tsx.
Tùy chọn
Spread props
Thêm {...props} vào thẻ <svg> gốc để nơi gọi truyền được className, onClick, aria-label… mà không phải sửa component. Ở chế độ TypeScript, prop được khai kiểu React.SVGProps<SVGSVGElement>.
Bỏ width/height
Xóa width và height cố định ở thẻ gốc. viewBox vẫn giữ nguyên nên icon co giãn theo CSS hoặc theo khung cha — đúng cách làm cho một bộ icon chỉnh size bằng w-4 h-4 hay font-size.
Dùng currentColor
Đổi mọi fill và stroke thành currentColor, trừ fill="none" vì giá trị này mang ý nghĩa thật ở icon dạng nét. Icon sẽ ăn theo color của khung chứa, nên hover và dark mode tự chạy đúng.
Bỏ metadata
Xóa comment, <title>, <desc>, <metadata> và rác của phần mềm thiết kế như sodipodi:namedview.
<title> chính là thứ trình đọc màn hình đọc lên cho icon. Nếu icon tự nó mang nghĩa (không đi kèm nhãn chữ), hãy giữ lại — hoặc thay bằng aria-label ở thẻ gốc.
Ví dụ
Đầu vào:
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path class="a" d="M4 12h16" stroke="#111" stroke-width="2" style="stroke-linecap:round"/>
</svg>
Kết quả (component, TypeScript, spread props, currentColor):
import * as React from "react";
export default function Icon(props: React.SVGProps<SVGSVGElement>) {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" {...props}>
<path className="a" d="M4 12h16" stroke="currentColor" strokeWidth="2" style={{ strokeLinecap: "round" }} />
</svg>
);
}
Câu hỏi thường gặp
File của tôi có bị tải lên đâu không?
Không. Việc phân tích và chuyển đổi diễn ra ngay trong trình duyệt.
Dùng được với Preact, Solid hay Vue JSX không?
Phần lớn là được. Preact và Solid chấp nhận cả class lẫn className nên kết quả dùng ngay được. Template Vue không phải JSX — ở đó cứ dùng SVG gốc.
Hai icon của tôi làm hỏng gradient của nhau sau khi import. Vì sao?
Vì cả hai file dùng chung id (a, gradient1, …) và trang bị trùng id. Hãy chạy từng file qua Chuẩn Hóa ID SVG với tiền tố riêng cho mỗi icon trước khi chuyển đổi.
Sao component vẫn nặng?
Công cụ này chỉ chuyển đổi cú pháp, không tối ưu hình học. Hãy chạy file qua Tối Ưu SVG trước để gộp path và cắt bớt số thập phân, rồi mới chuyển.
Xuất ra named export thay vì default export được không?
Không trực tiếp — hãy đổi sau khi dán. Kết quả cố ý là một function component đơn giản để bạn dễ sửa.
Khối <style> bên trong SVG thì sao?
Được giữ nguyên. Lưu ý tên class trong SVG có phạm vi toàn trang, nên hai icon cùng có class .a sẽ đè nhau — hãy chuẩn hóa hoặc đổi tên.