October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
Next.js

How to Use SVG in Next.js: Images, React Components, Styling, and Security

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use SVG as an ordinary image when you only need to display artwork; use inline SVG or an SVG-to-React loader when your code must style paths, pass props, or respond to state. In Next.js, the safest default is a file in public/ rendered with an image element. Convert imports to React components only when component-level control justifies bundler configuration, and treat untrusted SVG as active content rather than a harmless bitmap.

Choose the SVG representation first

Your integration choice follows the job the graphic must do:

Requirement Recommended approach What you gain
Display a logo, illustration, chart export, or diagram without changing its internal shapes Serve the file from public/ and render it as an image No loader or build configuration; stable URL and lossless scaling
Change fills, strokes, dimensions, or ARIA attributes from React Inline SVG JSX or an SVG-to-React component loader Props, conditional classes, and access to individual SVG elements
Allow users to download an SVG Link to the file or return it with download-oriented response headers Clear trust boundary and predictable browser behavior
Render an externally supplied or user-uploaded SVG Sanitize it and keep it in a restricted image/download context Reduced exposure to script, external-resource, and document-embedding risks

SVG is vector artwork, so it remains sharp at different sizes. Next.js documents that its Image component does not optimize SVGs by default; when the source is known to be SVG, use the documented unoptimized behavior rather than expecting raster-style optimization.

Display a static SVG from public/

1. Add the asset

Place the file at a stable path, for example public/images/diagram.svg. Files in public/ are referenced from the site root, so the browser URL is /images/diagram.svg.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

2. Use a normal image element

export default function ArchitectureDiagram() {
  return (
    <img
      src="/images/diagram.svg"
      alt="Request flow from the browser to the API"
      width={960}
      height={540}
    />
  )
}

This is the simplest choice when the SVG does not need internal styling. Supply intrinsic dimensions or an equivalent CSS aspect ratio to reduce layout movement. For a decorative image, use an empty alt value (alt="") instead of repeating nearby text.

Using next/image

You can also use next/image when its layout features fit your page:

import Image from 'next/image'

export default function Logo() {
  return (
    <Image
      src="/images/logo.svg"
      alt="Acme"
      width={180}
      height={48}
      unoptimized
    />
  )
}

Next.js says SVGs are not optimized by default because they already scale losslessly and can carry capabilities resembling HTML and CSS. The documentation recommends the unoptimized path when the source is known to be SVG, and notes that this is applied automatically when src ends in .svg. Check the version-specific Image documentation for the exact behavior of your installed Next.js release.

Write inline SVG when the markup itself needs control

Inline SVG is appropriate for a small icon or a graphic whose paths must react to state. JSX uses camelCase attribute names, such as viewBox, fillRule, and clipRule.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
export function StatusIcon({ ok = false }) {
  const color = ok ? 'var(--success)' : 'var(--warning)'

  return (
    <svg
      width="24"
      height="24"
      viewBox="0 0 24 24"
      role="img"
      aria-label={ok ? 'Successful' : 'Needs attention'}
      fill="none"
      stroke={color}
      strokeWidth="2"
      strokeLinecap="round"
      strokeLinejoin="round"
    >
      {ok ? (
        <path d="m5 12 4 4L19 6" />
      ) : (
        <>
          <path d="M12 4v9" />
          <path d="M12 17h.01" />
        </>
      )}
    </svg>
  )
}

Use a meaningful accessible name for informative graphics. For a decorative icon next to a visible label, use aria-hidden="true" and do not add a competing label. The available framework material does not establish a complete accessibility matrix for every SVG situation, so distinguish decorative icons from graphics that convey information and verify the pattern against your accessibility standard.

Import an SVG as a React component with SVGR

A loader can transform an imported .svg file into a component:

import Mark from './mark.svg'

export default function Header() {
  return <Mark width={120} height={32} aria-label="Acme" />
}

The exact setup depends on whether your project uses Turbopack or webpack and on your Next.js version. Do not paste a webpack rule into a Turbopack project unchanged.

Turbopack configuration

Current Next.js Turbopack documentation lists @svgr/webpack as a supported loader and shows this rule in next.config.js:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
/** @type {import('next').NextConfig} */
const nextConfig = {
  turbopack: {
    rules: {
      '*.svg': {
        loaders: ['@svgr/webpack'],
        as: '*.js',
      },
    },
  },
}

module.exports = nextConfig

Install the loader in your project before building:

npm install -D @svgr/webpack

The official Turbopack configuration page also documents loader options in object form. Earlier Next.js releases used an experimental.turbo key; turbopack is the current configuration key in the cited documentation (last updated February 27, 2026). If your installed version differs, follow its matching docs.

Webpack projects

Webpack projects need a webpack-specific rule and usually a decision about whether SVG imports should be components, URLs, or both. Because rule syntax and Next.js integration vary by release, consult the webpack configuration for your installed version rather than assuming the Turbopack example applies. A common migration problem is configuring SVGR for every SVG and then breaking code that expected a URL; separate component imports and URL imports deliberately, or keep static files under public/.

Useful SVGR options

Loader options can set a title-prop policy, replace hard-coded colors, or export a component format that matches your codebase. Keep the transformation narrow: converting a large illustration into a React component increases JavaScript size and gives React work that a plain image would avoid.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Style, size, and theme SVGs reliably

Prefer a viewBox for responsive scaling

A viewBox defines the internal coordinate system; CSS or JSX width and height define display size. Preserve the viewBox when resizing so the artwork scales without distortion.

Choose CSS variables or props for colors

For inline or SVGR output, set stroke and fill from props or CSS variables. This works only when the SVG paths do not contain fixed presentation attributes that override your styles. Remove or normalize those fixed colors during asset preparation if theme switching is required.

Do not expect external CSS to reach an image file

When an SVG is loaded through <img> or next/image, page CSS cannot select its internal paths. Use inline markup or a component transform for internal styling; otherwise style the image element itself (for example, its dimensions or opacity).

Load heavy artwork intentionally

Large, detailed SVGs can still cost download and parse time even though they are vector. Keep static artwork as an image, compress it during your asset pipeline, and avoid turning it into a component unless you need per-element control. For icons repeated throughout a list, consider a small component or sprite strategy rather than duplicating thousands of path nodes.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

SVG security: the embedding context matters

Next.js does not optimize SVG by default partly because SVG can include capabilities resembling HTML and CSS. The risk is not identical in every context.

  • Image context: browsers may disable JavaScript and external resource loading when an SVG is used as an image.
  • Document context: those restrictions do not apply in the same way when the SVG is opened directly or embedded with iframe, object, or embed.
  • Untrusted files: never treat user-uploaded SVG as inert artwork. Sanitize it, isolate it, or serve it for download.

These distinctions are described by MDN’s SVG image guidance. A file that is safe in an image element may not be safe when navigated to as a document.

If you enable dangerouslyAllowSVG

Next.js’s Image documentation warns that enabling SVG serving through the Image Optimization API requires care. Follow its recommendations for a content disposition that forces download and a restrictive Content Security Policy that blocks scripts and sandboxes the content. Do not enable the setting merely to make an error disappear, and do not use it as a substitute for sanitizing untrusted uploads. See the Next.js Image security guidance for the configuration details that match your release.

Common failures and fixes

Symptom Likely cause Fix
Module parse failed when importing .svg No SVG loader is configured, or the rule targets the wrong bundler Use public/ for a URL, or configure SVGR for the active Turbopack/webpack setup and restart the dev server.
The imported value is a URL, not a component Your existing rule emits a file URL Import the file as a URL intentionally, or adjust the rule so SVGR handles component imports.
SVG appears blank Missing or incorrect viewBox, zero dimensions, or CSS color matching the background Inspect the SVG’s viewBox, give the element dimensions, and check computed fill/stroke values.
Colors will not change with CSS Paths contain hard-coded fill/stroke attributes, or the SVG is in an image context Normalize the asset and render it inline/SVGR when internal styling is required.
Next Image warning or unexpected optimization behavior The source is SVG and the project assumes raster optimization Follow the documented unoptimized SVG path and verify behavior against your Next.js version.
Security review rejects an SVG upload feature Untrusted SVG is being served as a document or without policy controls Sanitize uploads, constrain them to an image/download context, and apply the CSP and content-disposition guidance before enabling SVG serving.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

A practical decision checklist

  1. Is the file trusted, versioned artwork? If yes, a public/ URL is usually enough.
  2. Must React change paths, colors, labels, or dimensions inside the SVG? Use inline SVG or SVGR.
  3. Does the project run Turbopack? Use the current turbopack.rules configuration; do not copy an old experimental.turbo example blindly.
  4. Does the project run webpack? Configure a webpack rule for that Next.js version, and decide how URL imports coexist with component imports.
  5. Could the SVG be supplied by a user or third party? Define sanitization, CSP, response headers, and an image-versus-document boundary before shipping.
  6. Is the graphic decorative or informative? Set its accessible name accordingly and test it with your chosen accessibility tooling.

Or skip the browser setup

If your real task is capturing a rendered page that contains SVG—not integrating SVG into the Next.js bundle—ScreenshotNeo returns a screenshot or PDF with one request. It accepts cookie and consent banners before capture, removes more than 60 known consent platforms plus newsletter popups and chat widgets, and lets you turn each cleanup step off. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed; response headers identify the page verdict and whether the request was billed.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools to Claude, Cursor, and other MCP clients. Every plan includes the feature set, including full-page capture with lazy images loaded, CSS-selector element capture, dark mode, device presets and custom viewports, retina scale, PDF paper/margins/landscape/page ranges, HTML/CSS-to-image, custom JavaScript and CSS, clicks, selector or network-idle waits, request/resource blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, chosen-TTL caching, signed image links, asynchronous webhooks, bulk capture for up to 100 URLs per call, a usage API, and an OpenAPI specification. Common parameter names used by other screenshot APIs also work.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo documentation for options and response headers.

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

The Free plan includes 1,000 screenshots each month without a card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

Frequently Asked Questions

Can I use an SVG from a remote URL with Next.js?

Yes, but treat it as external content: configure remote image handling only where needed, verify the source, and apply the same trust and embedding rules as any third-party SVG.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why does an SVG look sharp but still slow down my page?

Vector scaling does not remove transfer, parsing, or DOM costs. Very detailed files can be large; keep them as images, reduce path complexity, and avoid converting them into React components without a styling requirement.

Should I keep SVG files in src or public?

Use public when you want a stable URL and ordinary image rendering. Keep an imported file in src when your configured loader must transform it into a component.

The Bottom Line

For most Next.js pages, put trusted artwork in public/ and render it as an image. Choose inline SVG or SVGR only when React must control the SVG’s internal markup, and apply stricter policies whenever files can come from outside your codebase.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.