nextjs 加载 iconify 如何 SSR 化

Category:

Tags:

由于开发项目页面多且复杂,所以选择使用到 iconify 图标库。使用到的是 nextjs,由于 iconify 在ssr中的一些缺陷,只能通过 json 去将图标 ssr 化,导致搭配 vscode 插件 Iconify IntelliSense 预览图标和书写体验不佳,所以进行封装改善开发体验。

使用:

typescript
<AxIcon icon="line-md:close-circle-twotone" className="mr-2" size={48} />

完整代码

typescript
"use client"; import { cn } from "@/lib/utils"; import { icons as entypoIcons, IconifyJSON } from "@iconify-json/entypo"; import { icons as lineMDIcons } from "@iconify-json/line-md"; import { icons as phIcons } from "@iconify-json/ph"; import { icons as tablerIcons } from "@iconify-json/tabler"; import { replaceIDs } from "@iconify/react"; import { getIconData, iconToHTML, iconToSVG } from "@iconify/utils"; interface AxIconProps { icon: string; size?: string | number; className?: string; } export default function AxIcon({ icon, size = 16, className }: AxIconProps) { const [brand, iconName] = icon.split(":"); const brandIcons: Record<string, IconifyJSON> = { tabler: tablerIcons, entypo: entypoIcons, ph: phIcons, "line-md": lineMDIcons }; if (!brandIcons[brand]) return; const iconData = getIconData(brandIcons[brand], iconName); if (!iconData) return; const renderData = iconToSVG(iconData, { height: size, width: size }); const svgStr = iconToHTML(replaceIDs(renderData.body), { ...renderData.attributes, class: cn("!w-auto !h-auto", className) }); return <div dangerouslySetInnerHTML={{ __html: svgStr }} />; }