Frameworks
SVG Icons in Next.js: Complete Guide and Best Packs
How to use SVG icons in Next.js App Router projects: lucide-react, SVGR, next/image trade-offs, server components, and the best icon packs for Next.js in 2026.
SVG icons in Next.js look simple until the App Router asks awkward questions: does this icon render in a Server Component, does it hydrate, and what does it cost the bundle? This guide gives the patterns that survive production.
The App Router mental model for icons
In the Pages Router era, an icon was just a component in the bundle. The App Router adds a boundary: every file is a Server Component until a 'use client' directive says otherwise, and code only ships to the browser when it sits inside, or is imported by, a client component. Icons matter in this model because they are everywhere: a header, a sidebar and a pricing table can reference forty glyphs. If those files are server components, the icons render to HTML on the server and cost the client almost nothing beyond the markup. If the same files become client components for one interactive widget, every glyph they import joins the JavaScript bundle. Managing SVG icons in Next.js is therefore mostly boundary management, and the tools below are chosen with that lens.
The default: lucide-react in Server and Client Components
lucide-react components are plain SVG wrappers with no client-side state, so they render happily inside Server Components and stream with the page. Import icons by name, size them with className, and let tree-shaking do the rest. This covers 90 percent of Next.js apps. Preview the full set in Lucide on IconVault.
import { ArrowRight, Search } from "lucide-react";
export default function Page() {
return <Search className="h-5 w-5" aria-hidden />;
}The same holds for the other major component packages: Heroicons, Tabler and Phosphor React builds are all stateless presentational components, so they are equally at home on the server. What disqualifies a package from server files is never the icon itself; it is a dependency on hooks, context or browser APIs somewhere in its import chain. If an icon-related import forces a client boundary you did not plan, that is a packaging smell worth investigating rather than accepting.
Custom SVGs: SVGR vs a components folder
For brand marks and one-off glyphs you have two clean options. SVGR converts .svg files into components at build time, which suits design-system repos. A hand-maintained components/icons folder suits app codebases: paste the SVG, swap fills for currentColor, export a typed component. IconVault's SVG to JSX converter generates that component shape directly. Avoid next/image for icons: it is built for photographs, adds wrapper markup, and cannot inherit currentColor.
Setting up SVGR in Next.js
SVGR needs a webpack rule, added in next.config, that routes .svg imports to @svgr/webpack while keeping Next's file handling for other assets. On projects using Turbopack, the equivalent configuration lives under the turbopack rules key in recent Next.js versions. Whichever bundler you use, verify both directions after setup: an imported logo becomes a component, and an .svg referenced as a URL, for example in metadata or an img tag, still resolves as a file where you rely on that behaviour.
// next.config.mjs
const nextConfig = {
webpack(config) {
config.module.rules.push({
test: /\.svg$/i,
issuer: /\.[jt]sx?$/,
use: ["@svgr/webpack"],
});
return config;
},
};
export default nextConfig;TypeScript needs one declaration before SVGR imports type-check, because Next's generated types describe .svg modules as image data. Add a declarations file that tells the compiler the component type, and keep it next to your other ambient types:
// svg.d.ts
declare module "*.svg" {
import type { SVGProps } from "react";
const Component: (props: SVGProps<SVGSVGElement>) => JSX.Element;
export default Component;
}When the components folder beats SVGR
SVGR shines when designers drop finished artwork into a repo and engineers should not touch it. The components folder wins when icons are product code: you can add props for size and title, normalise stroke settings, write a test that every icon exposes aria-hidden by default, and refactor ten glyphs in one commit. Many mature codebases run both: SVGR for a brand and illustration directory that changes rarely, hand components for the interface set that evolves weekly. Run artwork through the SVG optimizer before either route, because neither SVGR nor good intentions remove editor cruft from source files.
Best icon packs for Next.js projects
- Lucide: the App Router default; server-component friendly and shadcn/ui's set. Browse.
- Heroicons: ideal with Tailwind; outline and solid variants for interactive states. Browse.
- Tabler Icons: when a dashboard needs breadth without a second package. Browse.
- Simple Icons: brand logos for auth buttons and footer socials. Browse.
- Phosphor: multiple weights for design systems that outgrow one stroke weight. Browse.
Choosing among them is mostly about the interface you are building. Content and marketing surfaces tolerate, and often prefer, the friendlier geometry of Phosphor or the editorial feel of Heroicons solid for emphasis states. Dense product UI rewards Lucide's discipline or Tabler's depth, where the four-hundredth glyph still matches the first. Let one constraint dominate: the set must cover your roadmap's needs without a second package, because the day a dashboard imports two families for coverage, visual consistency starts leaking. The libraries directory lists all 239 sets on IconVault with counts and licences, which makes the coverage check a ten-minute task instead of a mid-project surprise.
Dynamic icons without shipping the whole set
Some features genuinely need icons chosen at runtime: a link-in-bio builder where users pick a glyph, a category admin with an icon field, an icon picker in a CMS. The naive implementation imports a registry of the entire set and renders by name, which hands every visitor the full library for a feature a fraction of them open. In Next.js, structure it in layers. Keep a curated allow-list as a plain record mapping your names to lazy component imports. Render the picker itself with next/dynamic so its code splits into a chunk that loads when the picker opens. Store the user's choice as the icon name string, and resolve it through the same map at render time on both server and client, so there is no hydration mismatch.
import dynamic from "next/dynamic";
const IconPicker = dynamic(() => import("./IconPicker"), {
loading: () => <p className="text-sm">Loading icons...</p>,
});Note the boundary discipline: the dynamic import lives in the client component that owns the interaction, while the surrounding page stays a server component. If your picker truly needs thousands of glyphs searchable by name, fetch icon data on demand from an API route or render options as images from a CDN sprite workflow rather than bundling data; the full icon browser on IconVault exists precisely so end users do not need that machinery in your product.
Favicons and metadata icons in the App Router
Next.js treats site icons as file conventions: place icon.svg in the app directory for the favicon, apple-icon.png for Apple touch icons, and use the metadata API for Open Graph images. SVG favicons scale perfectly and support dark-mode media queries inside the file, and every modern browser accepts them, with a PNG fallback for legacy contexts. Keep the artwork brutally simple at 16px, since a detailed logo collapses into noise at tab size. Generate a complete, correctly sized set, including the ICO and touch variants, with the favicon generator, and remember that metadata images are brand assets, not interface icons, so they should not be forced into your icon system's stroke rules.
Styling and sizing conventions that scale
Adopt a small size scale and refuse improvisation: 16px inside controls and dense lists, 20px for toolbar and navigation actions, 24px for standalone and empty-state usage, with display sizes reserved for marketing surfaces. In Tailwind terms that is h-4, h-5 and h-6 doing nearly all the work, always paired so aspect ratio survives. Colour stays inherited through currentColor, with semantic tokens for status and the occasional brand exception. If your team uses CSS modules or vanilla CSS instead, the same rules translate into three utility classes. What matters is that the scale exists in writing, because icon sizing debates are unresolvable by taste at review time and trivially resolvable by a documented scale. Stroke width follows the set's native convention; do not let one team's preference for lighter icons fork the system.
Performance and accessibility checks
Keep icons out of client bundles when they only appear in server-rendered chrome like headers and footers, set explicit sizes to avoid layout shift, and label icon-only buttons properly. The deeper checklist lives in our guides to SVG icons and Core Web Vitals thinking and accessible SVG icons. For the React-wide picture, see the best React icon libraries.
- Audit the client bundle after icon changes with the bundle analyser; icon regressions hide in shared chunks and layouts, not in the page you edited.
- Check that layout and template files importing icons are server components unless they truly need interactivity, because a layout going client ships its icons to every route.
- Confirm icon-only buttons expose names in the accessibility tree; Next.js gives you no free pass here, it is the same aria-label and sr-only discipline as any React app.
- Verify no layout shift from icons by loading key pages with throttling; explicit sizes on icon components and image-based brand marks both matter.
- Prefer keeping marketing chrome server-rendered and measure first-load JS per route in the build output table Next prints, watching the shared-by-all figure.
Common errors and fixes
You are importing a component that needs use client
This error appears when a server component imports something whose chain touches client-only APIs. Pure icon packages do not cause it, so look past the icon in the import list to siblings: an interactive wrapper, a tooltip, or a package barrel that re-exports client utilities. Isolate the real offender, move the interactive part behind a small client component, and let the icons stay on the server where they were innocent.
The SVG import returns image data instead of a component
Without a working SVGR rule, importing an .svg gives you the static image object Next uses for img sources, and rendering it as a component fails or stringifies oddly. Confirm the webpack or Turbopack rule matches your file's issuer and extension, restart the dev server after config changes, since Next caches config at startup, and check that a conflicting rule for images is not claiming .svg first.
Icons render at the wrong size only in production
A dev-versus-production size difference usually means class purging: a dynamically constructed class string, such as a template that joins 'h-' with a variable, is invisible to Tailwind's scanner and the utility never gets generated. Use complete class names from a lookup record for dynamic sizes. The other classic cause is a global svg rule in a CSS file that only loads in one environment's cascade order; explicit width and height utilities on the component end the argument.
Bundle grew after adding an icon package
Inspect the analyser before blaming the package. The usual culprits are a barrel import inside a shared component, an icon registry built for a picker, or the package being imported by a client layout that every route inherits. Fix the import shape first: named imports from the package root, registries split behind dynamic imports, and shared chrome audited for accidental client directives. If the package itself lacks per-icon modules, wrap the glyphs you use as local components and drop the dependency, using artwork sourced from the set pages.
Pages Router projects: what still applies
Plenty of production Next.js apps still run the Pages Router, and nothing about icons forces a migration. lucide-react and friends work identically, SVGR configuration is the same webpack rule, and the components folder pattern predates the App Router entirely. The differences are emphasis: there is no server-component boundary to exploit, so every icon in a page's import graph is client JavaScript by default, which makes tree-shaking and dynamic imports for pickers more important, not less. next/image guidance is unchanged: keep it for photographs, not glyphs. If you later adopt the App Router route by route, icons are the easy part, since stateless icon components move across the boundary without modification.
Auth buttons and brand icons deserve extra care
Sign-in buttons are where Next.js apps most often break their own icon rules, because brand glyphs arrive from a different world than interface icons. Use the official marks from Simple Icons at their brand colours, resist tinting them to match your theme, and keep the provider name as visible text beside the glyph, which both major identity providers require in their branding guidance anyway. A button that reads 'Continue with Google' next to the accurate mark will outperform a row of anonymous glyphs on clarity and on audit day. These buttons usually live in server-rendered auth pages, so they cost no client JavaScript when built from components, one more reason to skip the image-based shortcut.
Icons in places components cannot go: OG images, email and PDFs
Next.js apps routinely need icon artwork outside the React tree. Open Graph images generated with next/og render through Satori, which accepts inline SVG as JSX but not component packages or external files in the way pages do; plan on pasting the few paths you need into the image template, styled explicitly, at display sizes where a simplified glyph reads better than the detailed interface version. Transactional email is stricter: most clients ignore SVG entirely, so icons in email templates should be small hosted PNGs rendered from your SVG sources with a tool like the SVG to PNG converter, with alt text doing the communicative work. Generated PDFs sit between the two, usually accepting embedded SVG through the rendering library. The principle is consistent: the icon system is the single source of artwork, and each output channel gets the format it can actually render.
import { ImageResponse } from "next/og";
export function GET() {
return new ImageResponse(
(
<div style={{ display: "flex", alignItems: "center", gap: 24 }}>
<svg width="64" height="64" viewBox="0 0 24 24" fill="none"
stroke="#0F766E" strokeWidth="2">
<circle cx="11" cy="11" r="7" />
<path d="M21 21l-4.3-4.3" />
</svg>
<span style={{ fontSize: 48 }}>Your headline</span>
</div>
),
{ width: 1200, height: 630 }
);
}RTL layouts and directional icons
If your Next.js app serves right-to-left locales, icons need a policy, because some glyphs are directional and some are not. Arrows, chevrons, back and forward affordances and progress indicators should mirror in RTL so the interface still points where the user's reading direction says forward is. Logos, clocks, magnifiers, settings gears and media symbols should never mirror; a flipped clock is simply wrong. Implement the distinction deliberately: a utility class or a dir-aware wrapper that applies a horizontal flip transform to the directional subset only, driven by the document direction Next already knows from your locale routing. Test with a real RTL locale during development rather than bolting it on later, because the bugs are the visual kind that automated tests rarely catch and users in those locales notice instantly.
Testing icons in a Next.js codebase
Two inexpensive habits catch most icon regressions. First, include the accessibility tree in component tests for icon-bearing controls: assert the button's name, not the presence of an svg node, so a refactor that swaps a labelled button for a bare glyph fails loudly. Second, screenshot the icon-dense routes, navigation, dashboard chrome and empty states, in your visual regression setup, and review diffs at production sizes rather than zoomed. Server components make one more check worthwhile: view the page source of a server-rendered route and confirm the svg markup is present in the HTML, which proves the boundary discipline is working and no icon is waiting on hydration to exist. When a bundle analyser report is part of release hygiene, icon package deltas deserve the same glance as any dependency, since they change silently and often.
The Next.js icon checklist
- One interface family, imported by name, with brand marks as the documented exception.
- Layouts and chrome stay server components, so their icons render as HTML instead of bundle weight.
- Custom artwork lives in components/icons or flows through a verified SVGR setup, with the ambient type declaration committed.
- Runtime icon selection uses a curated allow-list, and pickers load behind dynamic imports.
- Favicons use the App Router file conventions as SVG first, with generated PNG fallbacks.
- Icon-only controls expose accessible names, sizes are explicit, and bundle impact is checked after package changes.
Upgrading icon packages without breaking the build
Icon libraries evolve: glyphs get redrawn, renamed or occasionally removed, and a major version bump can turn a routine dependency update into a scavenger hunt of red imports. Keep upgrades boring by treating them as their own change. Read the release notes for renames, run a project-wide search for the affected names before bumping, and let the TypeScript compiler list every broken import after the bump rather than discovering them at runtime. Because named imports fail loudly at build time, icon packages are actually among the safest dependencies to upgrade aggressively, provided the upgrade is isolated. The dangerous pattern is the opposite: an icon package pinned forever because it is entangled with unrelated upgrades, quietly fossilising the visual language of the product.
A related habit is to record your icon decisions where future maintainers will find them. A short section in the project readme naming the chosen family, the size scale, the custom icons folder and the brand exception saves every new hire the same archaeology, and it turns design reviews from taste debates into consistency checks. The system documented in this guide is deliberately unremarkable: one family, named imports, server-first rendering, curated dynamics. Its value is not novelty; it is that every developer on the project can predict where an icon comes from and what it costs, on every route, without opening a bundle report in anger.
Choosing a pack for App Router versus Pages Router
The router changes less than you fear. Whether a project uses the App Router or the Pages Router, Next.js SVG icons render the same way: as components imported by name and rendered as SVG. The real difference is where the boundary falls: App Router projects can render icons in Server Components for free, while Pages Router projects render everything on the client by default, so the bundle conversation differs even though the icons do not. When teams evaluate how to use SVG icons in Next.js for a new project, the router question should therefore be settled on data-fetching and routing grounds, not icon grounds, and Next.js SVG icons should be chosen on coverage, stroke and licence. A pack that is right for the App Router is right for the Pages Router too, because icons are presentation, not routing.
Migration between routers keeps icons intact. Projects moving from Pages to App Router often fear a rewrite of their icon layer, but Next.js SVG icons survive the migration untouched when they are plain components: the same imports render in Server Components, and only the components around them change. The work that does arise is organisational, such as moving shared chrome into Server Components so icons render without client JavaScript, which is a performance win rather than a cost. Guidance on how to use SVG icons in Next.js during a migration should say this plainly, because teams delay valuable router upgrades over an icon rewrite that never needed to happen. Next.js SVG icons are among the most portable assets in a Next.js codebase, and that portability is worth protecting with clean component boundaries.
Design tokens for icons in Next.js and Tailwind
Tokens turn icon choices into system choices. In a Next.js plus Tailwind project, Next.js SVG icons should draw size and colour from tokens: a size scale for roles, a colour scale for states, and a stroke convention for the family. The token layer lives in the wrapper component or in CSS variables, and feature code consumes tokens rather than raw classes, so a redesign touches one file instead of every screen. When teams document how to use SVG icons in Next.js at scale, the token section is what separates a style guide from a wish list, because tokens are enforceable while advice is not. Next.js SVG icons behind tokens stay consistent through redesigns, rebrands and team growth, which is the entire purpose of a token system.
Keep tokens framework-agnostic where possible. A token defined as a CSS variable survives a move from Tailwind utilities to another styling approach, while a token baked into a Tailwind-only class does not, so the durable habit is variables for colour and a small component API for size. This matters for Next.js SVG icons because Next.js projects live for years and styling fashions change faster than icon needs do. For developers planning how to use SVG icons in Next.js for the long term, a variable-first token layer is cheap insurance: it costs nothing today and saves a migration tomorrow. Next.js SVG icons themed through variables also compose cleanly with dark mode, since the theme flip changes variables and every glyph follows without code changes.
Icons in navigation, sidebars and breadcrumbs
Navigation glyphs are the product's signature. Users learn a product's navigation icons before they learn its features, so Next.js SVG icons in sidebars and top bars should be chosen from the core of the set, frozen early, and changed only with a migration plan. Active states deserve one consistent treatment across every nav item, whether that is a filled variant, a colour shift or a background change, because mixed active treatments read as bugs. When teams prototype how to use SVG icons in Next.js navigation, they should build the full sidebar with real labels and real data, since Next.js SVG icons that look balanced in isolation often crowd each other beside 14px text. Navigation is the most-seen surface in any app, and icon discipline there pays off on every screen.
Breadcrumbs and wayfinding need restraint. Breadcrumb separators, back chevrons and home glyphs are small but high-frequency Next.js SVG icons, and their job is to be forgettable: consistent, quiet and identical on every page. The pattern that works is a single separator component, a single back-button treatment, and a rule that breadcrumbs never introduce a second icon family for decoration. For teams writing standards on how to use SVG icons in Next.js, the breadcrumb rule sounds trivial until the first marketing page adds a decorative arrow that leaks into the app. Next.js SVG icons in wayfinding roles should be boring by design, because wayfinding that draws attention to itself has failed at its job.
Icons in forms, tables and dashboards
Dense screens punish decorative icons. Dashboards pack Next.js SVG icons into tables, filters and cards, and the rule that keeps them readable is a strict size scale with decoration removed: 16px for row actions, 20px for toolbar actions, larger sizes only for section headers. A glyph that does not help the user act or understand should not be in a dense screen at all, because every decorative icon competes with data the user actually needs. When planning how to use SVG icons in Next.js dashboards, prototype with real data density, since Next.js SVG icons that look calm in an empty frame often feel noisy beside ten columns of numbers. The dashboard test is unforgiving and correct: remove the icon, and if the row gets clearer, the icon never belonged there.
Form icons hint, labels decide. A search glyph in a filter input or a calendar glyph beside a date field helps scanning, but Next.js SVG icons in forms must never carry meaning the label does not, since screen readers and keyboard users may never encounter the glyph. The accessible pattern is a visible label plus a decorative icon marked aria-hidden, with status icons in validation messages reinforcing text that already exists. For teams documenting how to use SVG icons in Next.js forms, this distinction is the whole accessibility story in one paragraph: decorative glyphs hidden, meaningful glyphs labelled, no glyph as the sole signal. Next.js SVG icons used this way make forms faster for everyone without excluding anyone.
Server and Client Component icon patterns in depth
Server Components are the free lunch for icons. Because icon components are stateless SVG, Next.js SVG icons render inside React Server Components with no client boundary, no hydration cost and no JavaScript shipped for the glyph itself. The practical consequence is that shared chrome such as headers, sidebars and footers should stay Server Components wherever possible, importing icons directly and streaming them with the page. When developers learn how to use SVG icons in Next.js, the Server Component pattern should be taught first, because it reframes icons from a bundle cost into a markup cost, which is nearly always cheaper. Next.js SVG icons in Server Components are the closest thing to free iconography the framework offers.
Client Components need the same discipline, not different icons. When a component must be a client component, for interactivity or state, its Next.js SVG icons follow the same rules: import by name, never through a namespace, and keep the icon list explicit so tree-shaking can do its job. The mistake to avoid is a client-side icon picker that imports the whole set for one feature; the allow-list map pattern from this guide's dynamic section exists precisely for that case. For teams finalising how to use SVG icons in Next.js, the rule to write down is that the client boundary changes where code runs, not how icons are chosen. Next.js SVG icons chosen well render identically on both sides of the boundary, and users should never be able to tell which side rendered the glyph they see.
Marketing pages and app UI in one repository
One repository, two icon registers. Most Next.js repositories serve a marketing site and an application from the same codebase, and Next.js SVG icons on a landing page are display graphics at 32 or 48px while app icons are controls at 16px. The healthy arrangement is one family with two documented treatments: a control treatment for the app and a display treatment for marketing, differing only in size and possibly stroke. When teams plan how to use SVG icons in Next.js across both surfaces, they should define the display treatment explicitly, because an undocumented display style drifts into the app within months. Next.js SVG icons with two documented registers stay coherent across the funnel, so a visitor who signs up meets glyphs they already recognise.
Guard the boundary between registers. If marketing demands a second, more expressive family for hero graphics, confine it to marketing sections and forbid it in application chrome, with the boundary written in the icon readme rather than enforced by hope. Review marketing pull requests for icon leakage the way app pull requests are reviewed for it, because the leak direction is almost always marketing into product. For developers maintaining how to use SVG icons in Next.js in a growing company, this boundary is what prevents the slow accumulation of a second system inside the product. Next.js SVG icons that respect the boundary keep the product feeling like one designed object, even as the marketing site experiments freely.
Performance budgets for icons
Give icons a budget line. A performance budget that names an icon allowance, for example a maximum number of distinct glyphs per route or a byte ceiling for icon packages, turns icon discipline from advice into a number CI can check. The measurement is straightforward: run the bundle analyser per route, record the icon contribution, and fail the build when a route exceeds its allowance without justification. When teams adopt how to use SVG icons in Next.js with budgets, they discover that most violations come from a single careless import or a picker that slipped past review, both fixable in minutes. Next.js SVG icons with a budget stay small because the budget makes growth visible before it becomes a problem.
Audit routes, not just the app total. An app-level icon total hides the route that imports three families for one screen, so the audit should be per route, using Next.js build output and the analyser's per-page breakdown. The routes to watch are dashboards and settings screens, where feature teams add icons without coordinating, and the fix is usually a mapping exercise rather than a rewrite. For teams practising how to use SVG icons in Next.js responsibly, a quarterly per-route audit is a one-hour habit with a measurable payoff in load time. Next.js SVG icons audited per route are icons under control, and control is what lets a team keep adding features without the bundle quietly doubling.
Accessibility: icon buttons, focus and reduced motion
Icon-only buttons need names, not tooltips alone. A tooltip that appears on hover helps mouse users and nobody else, so Next.js SVG icons in icon-only buttons need an accessible name through aria-label or sr-only text, naming the action rather than the glyph. The wrapper is the enforcement point: require a label prop whenever no visible text accompanies the icon, so the rule cannot be forgotten at individual call sites. When writing standards for how to use SVG icons in Next.js accessibly, this requirement should be a hard rule with examples, because icon-only buttons are the most common accessibility failure in Next.js applications. Next.js SVG icons without labels are decoration; with labels, they are controls, and the difference is the whole product for some users.
Focus rings and reduced motion complete the contract. A keyboard user must see where focus sits on every icon button, so the button component must guarantee a visible focus ring that survives theming, and a motion-sensitive user must be able to disable icon animations through prefers-reduced-motion. Test both with a keyboard and with reduced motion enabled, tabbing through navigation, toolbars and dialogs, since these are the surfaces where Next.js SVG icons concentrate. For teams finalising how to use SVG icons in Next.js, a fifteen-minute keyboard and motion pass catches the failures automated tools miss. Next.js SVG icons that are labelled, focusable and motion-respectful meet the baseline for shipping to real users, not an optional extra.
Upgrading and documenting the icon system
Upgrade icon packages in dedicated pull requests. Icon sets occasionally rename glyphs between releases, and a rename that arrives bundled with a feature release becomes a confusing scavenger hunt, while the same rename in its own pull request is a five-minute fix. Pin Next.js SVG icons packages to tested versions, read the release notes for renames before upgrading, and grep the codebase for affected names as part of the upgrade. When teams plan how to use SVG icons in Next.js over years, this boring discipline is what keeps the system boring, and boring is the goal. Next.js SVG icons upgraded deliberately never surprise a release, because the surprise was already handled in its own reviewable change.
The icon readme is part of the system. A short document stating the chosen family, the size scale, the wrapper location, the mapping table and the upgrade procedure saves every future contributor from archaeology, and it should be updated in the same pull request as any icon change. Add a visual catalogue, whether in Storybook or a simple page, rendering every approved glyph at its approved sizes with its import path, so proposals for new glyphs can be judged against the existing set. For developers handing over how to use SVG icons in Next.js to a growing team, the readme and catalogue are what turn a personal preference into a team standard. Next.js SVG icons with documentation outlast the people who chose them, which is the truest test of any engineering decision.
Responsive sizing in Next.js apps
Breakpoints change chrome, not glyphs. For Next.js SVG icons, the glyph should stay constant while the layout adapts, and Next.js SVG icons that change size per breakpoint make an app feel different on every device. Teams planning how to use SVG icons in Next.js responsively should size icons by role rather than by screen, because Next.js SVG icons sized by role stay consistent from phone to desktop. The advice on how to use SVG icons in Next.js at responsive scale is to audit the smallest viewport first, since Next.js SVG icons that work at 360px work everywhere else.
Collapse toolbars instead of shrinking glyphs. For Next.js SVG icons, shrinking below 16px on small screens trades legibility for completeness, and Next.js SVG icons hidden behind an overflow menu preserve both. Teams designing how to use SVG icons in Next.js for mobile should define a collapse order per toolbar, because Next.js SVG icons without a plan overflow or crowd. The practice for how to use SVG icons in Next.js on small screens is a documented order, so Next.js SVG icons degrade predictably instead of breaking the layout.
Directional icons and RTL in Next.js
Mirror arrows when direction flips. For Next.js SVG icons, directional glyphs such as back, forward and chevrons must mirror in right-to-left layouts, and Next.js SVG icons that ignore direction confuse users who read right to left. Teams implementing how to use SVG icons in Next.js internationally should use logical utilities that flip automatically, because Next.js SVG icons handled with manual overrides rot with every redesign. The standard for how to use SVG icons in Next.js across locales is a documented list of directional glyphs, so Next.js SVG icons mirror exactly where they should.
Verify RTL with a real locale run. For Next.js SVG icons, English screenshots cannot prove RTL correctness, and Next.js SVG icons in a mirrored layout must be checked by running the app in an RTL locale and navigating through it. Teams testing how to use SVG icons in Next.js globally should add one RTL screen to their visual regression suite, because Next.js SVG icons that fail there are cheap to fix and costly to ship. The discipline for how to use SVG icons in Next.js at global scale is a locale pass before every release, so Next.js SVG icons never become an afterthought.
Icons in loading and error states
Loading states deserve purpose-drawn glyphs. For Next.js SVG icons, a loading spinner built from a generic icon looks cheap, and Next.js SVG icons in loading.tsx deserve a clean circular arc that reads at small sizes. Teams designing how to use SVG icons in Next.js loading states should keep the spinner consistent across routes, because Next.js SVG icons that change per route make waiting feel longer. The guidance on how to use SVG icons in Next.js for loading is one spinner, one size scale, and Next.js SVG icons that never distract from the content that is coming.
Error pages need calm, recognisable iconography. For Next.js SVG icons, an error.tsx page should use a single restrained glyph plus clear text, and Next.js SVG icons that shout on an error page add stress to an already bad moment. Teams planning how to use SVG icons in Next.js error states should pair the glyph with a recovery action, because Next.js SVG icons beside a retry button guide users forward. The rule for how to use SVG icons in Next.js error handling is restraint: one glyph, one message, one action, so Next.js SVG icons help users recover instead of decorating their frustration.
A request process for new Next.js icons
Route new glyphs through a request template. For Next.js SVG icons, a short template asking for the meaning, the screen and the nearest existing glyph prevents most duplicates, and Next.js SVG icons added through requests stay inside the documented family. Teams formalising how to use SVG icons in Next.js at scale should review requests weekly, because Next.js SVG icons requested during feature work are how second families enter a codebase. The habit for how to use SVG icons in Next.js in growing teams is weekly request review, so Next.js SVG icons grow deliberately rather than accidentally.
Answer requests with the existing set first. For Next.js SVG icons, the most common outcome is discovering the set already covers the need, and Next.js SVG icons found this way cost nothing and keep the system intact. Teams stewarding how to use SVG icons in Next.js should reply with a screenshot of the closest existing glyph at production size, because Next.js SVG icons judged at poster size mislead requesters. The principle for how to use SVG icons in Next.js over years is slow, deliberate growth, so Next.js SVG icons added today still belong to the same family tomorrow.
Onboarding developers onto the Next.js icon system
Teach the wrapper and the budget on day one. For Next.js SVG icons, a new developer's first lesson should be the wrapper, the size tokens and the per-route budget, and Next.js SVG icons explained through those three things become a system rather than a folder of imports. Teams onboarding around how to use SVG icons in Next.js should put icon conventions in the onboarding checklist, because Next.js SVG icons are often the first code a newcomer touches. The guidance for how to use SVG icons in Next.js in hiring teams is that conventions taught early are conventions kept, so Next.js SVG icons stay consistent through turnover.
Review the first icon change as teaching. For Next.js SVG icons, a newcomer's first glyph addition or swap, reviewed against the checklist, teaches more than any document, and Next.js SVG icons handled in a reviewed first task set the standard for everything after. Teams practising how to use SVG icons in Next.js with new hires should treat that review as teaching, because Next.js SVG icons reviewed early prevent habits that audits later punish. The rule for how to use SVG icons in Next.js at team scale is that every developer's first icon change is reviewed, so Next.js SVG icons remain a shared standard.
Frequently asked questions
Do lucide-react icons work in Server Components?
Yes. Lucide icons are stateless components that render SVG markup, with no hooks or browser dependencies, so they work in Server Components and stream as HTML. The same is true of Heroicons, Tabler and Phosphor React packages. A client boundary is only required when the importing component itself needs interactivity or browser state.
Should I use next/image for icons in Next.js?
No. next/image is engineered for raster photographs: it adds wrapper markup, serves resized image files, and cannot inherit currentColor or respond to CSS colour. Icons should be inline SVG components, which scale cleanly, theme with the page and cost no extra requests. Reserve next/image for photos, screenshots and generated Open Graph assets.
What is the best icon library for Next.js in 2026?
For most App Router projects, Lucide is the safest default: server-friendly, tree-shaken by named imports, and the set shadcn/ui builds on. Choose Heroicons for a Tailwind-first marketing feel, Tabler when a dashboard needs unusual breadth, and Phosphor when your design system needs multiple weights. All four are browsable side by side on IconVault.
How do I use my own SVG files as Next.js components?
Either configure SVGR to transform .svg imports into components, or maintain a components/icons folder of hand-written components. For app codebases the folder is usually better: you control props, defaults and accessibility, and artwork normalised through an SVG to JSX converter drops straight in. Add the ambient module declaration so TypeScript accepts the imports either way.
Why did my First Load JS grow after adding icons to the layout?
Layouts ship to every route, so their imports are everyone's cost. If the layout or a component it imports carries a client directive, its icons join the shared client bundle; if it imports icons through a barrel or registry, the whole set can follow. Keep layouts as server components, import icons by name, and split any picker-style registries behind dynamic imports.
Find the icons from this guide
Search 421,020 free SVG icons from 239 libraries in one place.