Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Blade Flags Laravel Package

outhebox/blade-flags

1,759 SVG country and language flags for Laravel Blade, Vue, React, and vanilla JS. Three flag styles, 128 language mappings, and regional variants like ar-sa, en-us, and fr-ca. Works with Inertia.js.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require outhebox/blade-flags
    

    For frontend frameworks (keep core and framework adapters on the same minor, e.g. all 0.3.x):

    npm install @blade-flags/core@^0.3.0 @blade-flags/vue@^0.3.0   # Vue
    npm install @blade-flags/core@^0.3.0 @blade-flags/react@^0.3.0 # React
    
  2. First Use Case: Insert a country flag in a Blade view:

    <x-flag-country-us />
    

    Or a language flag:

    <x-flag-language-en />
    
  3. Where to Look First:

    • README.md for Blade syntax
    • SVG directories for available flags
    • node_modules/@blade-flags/core/flags/ for the per-flag module paths shipped since 0.3.0
    • Blade Icons docs for caching and advanced usage

Implementation Patterns

Blade Integration

  1. Static Flags: Use predefined components for known flags:

    <x-flag-circle-country-gb class="w-8 h-8" />
    <x-flag-flat-language-es />
    
  2. Dynamic Flags: Use @svg directive for runtime-generated flag names:

    @svg('flag-country-'.$user->country_code)
    @svg('flag-circle-language-'.$user->language_code, ['class' => 'text-blue-500'])
    
  3. Helper Method:

    // In a controller or service
    public function getFlagSvg($countryCode) {
        return svg("flag-country-{$countryCode}")->toHtml();
    }
    

Frontend Integration (Vue/React)

  1. Dynamic Rendering:

    <script setup>
    import { Flag } from '@blade-flags/vue'
    import { circleFlags } from '@blade-flags/core/flags/circle'
    </script>
    
    <template>
      <Flag :code="user.country" :flags="circleFlags" />
    </template>
    
  2. Static Import (single flag): Since 0.3.0, every flag is its own module, so you can deep-import exactly one:

    import countryUs from '@blade-flags/core/flags/circle/country-us'
    import languageAr from '@blade-flags/core/flags/circle/language-ar'
    

    Barrel imports (from '@blade-flags/core/flags/circle') still work, but pull the whole set into the graph.

  3. Code-Split Loading (new in 0.3.0): The per-flag module layout makes a one-flag-per-chunk lazy load possible:

    const loadFlag = (code) =>
        import(`@blade-flags/core/flags/circle/country-${code}`)
            .then(m => m.default)
    
    const flag = await loadFlag(user.country)
    
  4. Inertia.js: Pass flag data from Laravel to Vue/React via page props:

    return Inertia::render('Profile', [
        'user' => $user,
        'flags' => ['country' => $user->country_code, 'language' => $user->language_code]
    ]);
    

Common Workflows

  1. Locale Switcher:

    <div class="flex gap-2">
        @foreach($availableLanguages as $lang)
            <x-flag-circle-language-{{ $lang->code }} class="cursor-pointer"
                wire:click="changeLanguage('{{ $lang->code }}')"/>
        @endforeach
    </div>
    
  2. User Profile:

    <div class="flex items-center gap-3">
        <x-flag-country-{{ $user->country }} class="w-10 h-8" />
        <span>{{ $user->name }}</span>
    </div>
    
  3. Admin Dashboard:

    <table>
        @foreach($users as $user)
            <tr>
                <td><x-flag-country-{{ $user->country }} /></td>
                <td>{{ $user->name }}</td>
            </tr>
        @endforeach
    </table>
    

Gotchas and Tips

Pitfalls

  1. CSS Sizing:

    • Flags may ignore Tailwind classes like w-6 h-6 if hardcoded width/height exists in SVG.
    • Fix: Use width="100%" height="100%" in SVG or wrap in a container with explicit dimensions.
    • Example:
      <div class="w-6 h-6">
          <x-flag-country-us />
      </div>
      
  2. Missing Flags:

    • Not all countries/languages are supported (check SVG directories).
    • Workaround: Use regional variants (e.g., en-us instead of en) or fall back to a generic flag.
  3. Caching:

    • Blade Icons (underlying package) caches SVGs. Clear cache if flags don’t update:
      php artisan view:clear
      php artisan cache:clear
      
  4. Dynamic Flag Names:

    • Ensure $country->iso2_code or $language->code matches the package’s naming convention (e.g., us, en, ar-sa).
    • Debug: Check available flags in resources/svg/ or use php artisan tinker to inspect:
      \Outhebox\BladeFlags\Facades\BladeFlags::availableFlags();
      
  5. Version Skew Between JS Packages (0.3.0):

    • @blade-flags/react and @blade-flags/vue 0.3.0 track the core version. Mixing [email protected] with an older adapter (or vice versa) can break flag resolution and the new per-flag module paths.
    • Fix: bump them together and lockstep them in package.json; check npm ls @blade-flags/core.
      npm install @blade-flags/core@^0.3.0 @blade-flags/vue@^0.3.0
      
  6. Bundler Handling of Variable Dynamic Imports:

    • import(\@blade-flags/core/flags/circle/country-${code}`)` is only statically analyzable up to the interpolation point. Vite/webpack build a context module for the whole directory, which can negate the chunking win or emit warnings.
    • Fix: give the bundler a hint — a static map of supported codes, or in Vite:
      const flagModules = import.meta.glob('/node_modules/@blade-flags/core/flags/circle/country-*.js')
      const loadFlag = (code) => flagModules[`/node_modules/@blade-flags/core/flags/circle/country-${code}.js`]()
      
    • Validate code against an allow-list before interpolating into the specifier (untrusted input → failed chunk fetch at runtime).

Debugging

  1. Inspect SVG Output:

    {{ \Outhebox\BladeFlags\Facades\BladeFlags::svg('flag-country-us')->toHtml() }}
    

    Look for malformed tags or missing attributes.

  2. Check Published Assets: If using raw SVGs, verify they exist in:

    public/vendor/blade-flags/country-us.svg
    
  3. Frontend Debugging:

    • For Vue/React, log the resolved flag code:
      console.log(resolveFlag(circleFlags, 'us')); // Check if SVG is valid
      
    • For lazy loading, log the module shape — the per-flag module’s default export is the flag, not a named one:
      const m = await import('@blade-flags/core/flags/circle/country-us')
      console.log(Object.keys(m), m.default)
      

Configuration Quirks

  1. Language Overrides:

    • Overrides require republishing SVGs:
      php artisan vendor:publish --tag=blade-flags-config
      php artisan blade-flags:generate
      
  2. Blade Icons Compatibility:

    • If using Blade Icons’ BladeIcon::resolve(), ensure the package is installed:
      composer require blade-ui-kit/blade-icons
      
  3. Inertia.js:

    • Flags in Vue/React must match the variant (e.g., circleFlags) used in Blade for consistency.

Extension Points

  1. Custom Flags:

    • Add your own SVGs to public/vendor/blade-flags/ and reference them via @svg('custom-flag').
  2. Flag Variants:

    • Extend the package by creating a new variant (e.g., square-flags) by copying the build script and SVG templates.
  3. Dynamic Generation:

    • Use the resolveFlag() helper to build flags programmatically:
      $svg = \Outhebox\BladeFlags\Facades\BladeFlags::resolve('circle', 'country', 'us');
      

Performance Tips

  1. Deep Imports Over Barrel Imports (0.3.0):

    • Import the exact flag module when you only need a handful; the barrel module drags in every flag for that variant:
      import countryUs from '@blade-flags/core/flags/circle/country-us'
      
  2. Lazy Loading / Code Splitting:

    • The one-module-per-flag layout lets each flag ship as its own chunk — ideal for SPAs with a large, rarely-shown flag set:
      const loadFlag = async (code) => {
          const { default: flag } = await import(`@blade-flags/core/flags/circle/country-${code}`)
          return flag
      }
      
    • Preload the handful of flags above the fold, lazy-load the rest.
  3. Blade Caching:

    • Disable caching for development:
      // config/blade-flags.php
      'cache' => env('APP_ENV') !== 'local',
      
  4. Measure the Chunk Graph:

    • After switching to deep imports, verify the win with npx vite build --debug or webpack-bundle-analyzer — a single stray barrel import re-inlines the whole set.

Pro Tips

  1. Combine with Blade Icons:

    • Use Blade Icons’ features like size and color:
      <x-flag-country-us size="2x" color="#0000FF" />
      
  2. Dark Mode:

    • Override SVG colors for dark mode:
      <x-flag-country-us class="dark:invert" />
      
  3. Accessibility:

    • Add aria-label for screen readers:
      <x-flag-country-us aria-label="United States" />
      
  4. Regional Variants:

    • Use - for regional flags (e.g., ar-sa for Arabic-Saudi Arabia), and mirror that naming in any dynamic import path:
      <x-flag-circle-language-ar-sa />
      
  5. Testing:

    • Test dynamic flags with edge cases:
      // Test invalid flag codes
      $this->blade->render('@svg("flag-country-xx")')->assertSee('Invalid flag code');
      
    • Test the lazy loader against unknown codes so a bad code fails gracefully instead of throwing a chunk-load error:
      await expect(loadFlag('xx')).rejects.toThrow();
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle