10000 GitHub - timhettler/symbol-store: Combine SVGs into a single file with Symbol definitions
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Combine SVGs into a single file with Symbol definitions

License

Notifications You must be signed in to change notification settings

timhettler/symbol-store

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Symbol Store

An opinionated command-line tool to combine multiple SVG files into a single file that utilizes the <symbol> element.

Features

  • SVG optimization using SVGO
  • Removal of fill and stroke attributes so they may inherit from parent CSS.
  • (Optional) Type-safe React component export.

Motivation

For many years SVGR has been the de facto solution for rendering SVGs in React apps. (Perhaps because it was bundle with Create React App.) However, after working on production-facing, high-traffic websites for many years, I've realized that importing SVGs one-by-one as React components has real performance issues, mainly:

When Should You Use This Library?

This library is most useful when you have a large number of monochrome SVGs to display on a website - perhaps in multiple places on a single page - and the fill color needs to be modified. That is to say, this library is for icons. Complex SVGs are outside the concerns of this library. For those types of SVGs, I recommend creating a separate process to optimize with SVGO and to import them on an ad-hoc basis.

While stroke manipulation is possible, it is a best practice to export SVGs with "outlined strokes" so all files can be manipulated predictably.

Installation

yarn add @timhettler/symbol-store

Usage

symbol-store -i ./icons -o ./public -t ./src/components

Options

Run symbol-store -h for details in your terminal.

Option Required Description Default
-i Y Path containing SVG files N/A
-o N Path to output the combined SVG Input path
-t N Create a TypeScript file? Output path
-r N Add random suffix to filenames false
-p N URL to proxy SVG requests N/A

Cross-Origin Requests

The SVG <use> element does not work with cross-origin requests. If your symbol is hosted on a different domain than your application, you'll need to proxy the request. Here's an example using Next.js route handlers:

symbol-store -i ./icons -o ./public -t ./src/components -p /api/symbol-store

This will generate a React component that uses the proxy URL:

export const UseSvg = ({ node, ...props }: UseProps) => (
  <svg {...props}>
    <use href={`/api/symbol-store#${node}`} />
  </svg>
);

You'll need to create a route handler to proxy the requests:

// app/api/symbol-store/route.ts
import { NextResponse } from "next/server";
import { PHASE_DEVELOPMENT_SERVER } from "next/constants";

export async function GET() {
  const isDev = process.env.NEXT_PHASE === PHASE_DEVELOPMENT_SERVER;

  const svgUrl = isDev
    ? "/symbolstore.svg"
    : "https://cdn.mydomain.com/symbolstore.svg";

  const res = await fetch(svgUrl);
  const svg = await res.text();

  return new NextResponse(svg, {
    headers: {
      "Content-Type": "image/svg+xml",
      "Cache-Control": "public, max-age=31536000",
    },
  });
}

Preloading

Since the SVG symbol file is critical for rendering icons, it's recommended to preload it to avoid render-blocking requests. This is especially important if you're using a proxy endpoint, as the request will need to complete before any icons can be displayed.

Next.js

Add the preload tag to your root layout:

<head>
  <link rel="preload" href="/symbolstore.svg" as="image" type="image/svg+xml" />
</head>

If you're using a proxy endpoint, preload that instead:

<head>
  <link
    rel="preload"
    href="/api/symbol-store"
    as="fetch"
    crossorigin="anonymous"
  />
</head>

Note: Using as="fetch" instead of as="image" when preloading the proxy endpoint ensures the browser makes a single request that can be reused by the <use> elements.

References & Prior Art

About

Combine SVGs into a single file with Symbol definitions

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published
0