Named imports
Recommended for SSR and CSR. They are synchronous, tree-shakeable, and require no client-only boundary.
The flag packages render inline SVG and do not need browser APIs. Named flag imports and
DynamicFlag can therefore render in the first server response with Next.js and Nuxt.
Named imports
Recommended for SSR and CSR. They are synchronous, tree-shakeable, and require no client-only boundary.
DynamicFlag
SSR-safe and synchronous, but it imports the complete flag registry. Use it only when the code cannot be bounded at build time.
CircleFlag
Deprecated. It fetches SVG after mounting, so the server can only render its loading state. Do not use it when the flag must appear in the initial HTML.
| Rendering | Stack | Verification |
|---|---|---|
| CSR | React + Vite 8 | TypeScript and production bundle build |
| SSR | Next.js App Router + React | Production build, server startup, first-response SVG assertion |
| CSR | Vue 3 + Vite 8 | Vue TypeScript and production bundle build |
| SSR | Nuxt 4 + Vue 3 | Nuxt typecheck/build, Nitro startup, first-response SVG assertion |
| CSR | Svelte 5 + Vite 8 | Svelte compiler and production bundle build |
| CSR | Solid.js + Vite 8 | TypeScript and production bundle build |
App Router files are Server Components by default. Consumers do not need to add a use client
directive: the React package entry declares its own boundary because it also exposes the deprecated,
hook-based CircleFlag. Next.js can still prerender named flags and DynamicFlag into the first
HTML response.
import { DynamicFlag, FlagJp } from '@sankyu/react-circle-flags'
export default function Page() { return ( <main> <FlagJp width={64} height={64} title="Japan" /> <DynamicFlag code="de" width={64} height={64} title="Germany" /> </main> )}Keep the import at the public package entry. Importing generated files or internal source paths bypasses the package export map and can fail when Next.js resolves the server graph.
Import Vue components directly in <script setup>. Do not wrap named flags or DynamicFlag in
<ClientOnly>; doing so removes the flag markup from the initial HTML.
<script setup lang="ts">import { DynamicFlag, FlagJp } from '@sankyu/vue-circle-flags'</script>
<template> <main> <FlagJp :width="64" :height="64" title="Japan" /> <DynamicFlag code="de" :width="64" :height="64" title="Germany" /> </main></template>Vite 8 uses a newer Node.js baseline. This affects the example toolchain, not the browser runtime of the published flag packages. Use a Node.js version accepted by your chosen framework; the monorepo uses the stricter Nuxt-compatible range so every example can share one environment.
Use @vitejs/plugin-react and strict subpaths such as @sankyu/react-circle-flags/flags/us.
Use @vitejs/plugin-vue and strict subpaths such as @sankyu/vue-circle-flags/flags/us.
Use @sveltejs/vite-plugin-svelte and import named components from
@sankyu/svelte-circle-flags.
Use vite-plugin-solid and strict subpaths such as @sankyu/solid-circle-flags/flags/us.
Replace deprecated CircleFlag with a named import or DynamicFlag. CircleFlag performs a
client-side network request after mount and cannot embed the fetched SVG during SSR.
DynamicFlag intentionally includes all flags for arbitrary runtime codes. Prefer per-flag
subpaths, or create a finite map of those imports when runtime values come from a known set. The
main entry remains convenient, but strict flags/* subpaths provide deterministic bundle isolation.
Build the package before the framework example. From this repository, pnpm run test:examples
builds packages first, then every compatibility app, and finally verifies the production SSR
responses.