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 Weather Icons Laravel Package

codeat3/blade-weather-icons

Easily add Weather Icons to Laravel Blade views with this lightweight component package. Install via Composer and use simple x-weather-icon tags to render scalable, customizable icons anywhere in your templates, with no manual SVG handling required.

View on GitHub
Deep Wiki
Context7

Getting Started

Install

composer require codeat3/blade-weather-icons

No service provider registration, no config publish, no asset build step. Laravel package auto-discovery registers the icon set with blade-ui-kit/blade-icons, which this package depends on.

Verify the actual component API before writing templates. The docs are inconsistent — the package description shows <x-weather-icon name="day-sunny" /> while other notes show <x-weather-icon-day-sunny />. Don't guess; list the shipped SVGs and try one of each form:

# the shipped icon names are the source of truth, not the README
find vendor/codeat3/blade-weather-icons -name '*.svg' | head -20

Then drop this into a scratch Blade view and load it:

<x-weather-icon name="day-sunny" />
{{-- or --}}
<x-weather-icon-day-sunny />

Whichever renders an <svg> is the real API for your installed version. Note it down for the team.

First real use case — a current-conditions card. Don't start with a grid. Build one card, because it forces you to answer the two questions you actually need answered: what does the icon look like at your sizes/colors, and what is the mapping from your weather provider's condition codes to icon names.

<div class="flex items-center gap-3">
    <x-weather-icon name="day-sunny" class="h-12 w-12 text-amber-400" />
    <div>
        <p class="text-3xl">{{ $weather->temp }}°</p>
        <p class="text-sm text-gray-500">{{ $weather->summary }}</p>
    </div>
</div>

Where to look first in the repo

  1. composer.json at the installed tag — check the illuminate/* range and PHP floor, both to confirm it supports your Laravel version and to see whether 1.8.0 widened or replaced the constraints versus 1.7.0.
  2. The SVG directory — authoritative icon names.
  3. blade-ui-kit/blade-icons docs — this package delegates all rendering behavior (attribute passing, class merging, caching) to it, so that's where the real semantics live.

Implementation Patterns

The one pattern that matters: a domain wrapper

Do not let templates pass provider strings or raw icon names around. Build exactly one thin component that owns mapping, fallback, and accessibility, then use it everywhere.

// app/View/Components/WeatherGlyph.php
namespace App\View\Components;

use Illuminate\View\Component;

class WeatherGlyph extends Component
{
    public function __construct(
        public ?string $code = null,        // provider code, e.g. OpenWeather "01d"
        public string $size = 'md',
        public ?string $label = null,      // omit => decorative
    ) {}

    public function icon(): string
    {
        return config('weather.icons.' . $this->code, 'cloudy'); // always resolves
    }

    public function render()
    {
        return view('components.weather-glyph');
    }
}
{{-- resources/views/components/weather-glyph.blade.php --}}
<x-weather-icon
    :name="$icon()"
    @class([
        'h-6 w-6' => $size === 'sm',
        'h-10 w-10' => $size === 'md',
        'h-16 w-16' => $size === 'lg',
    ])
    @if($label)
        role="img" aria-label="{{ $label }}"
    @else
        aria-hidden="true" focusable="false"
    @endif
/>

Two things this buys you: unknown codes can never reach the package (the only customer-facing failure mode becomes impossible), and the package stays swappable behind a single file.

The mapping layer is your code, not the package's

Put condition-code → icon-name in a config file so non-engineers can edit it and it's reviewable in isolation. This is the actual engineering work the package does not do for you.

// config/weather.php
return [
    'icons' => [
        // OpenWeather-style codes
        '01d' => 'day-sunny',
        '01n' => 'night-clear',
        '02d' => 'day-cloudy',
        '02n' => 'night-alt-cloudy',
        '03d' => 'cloud',
        '09d' => 'rain',
        '10d' => 'day-rain',
        '11d' => 'thunderstorm',
        '13d' => 'snow',
        '50d' => 'fog',
    ],
    'fallback' => 'cloudy',
];

The fallback is not optional. The upstream Weather Icons set is effectively frozen — a missing icon is a permanent gap, not a bug that gets fixed upstream.

Styling with Tailwind (and what actually works)

Sizing and color work the way you'd expect if the SVGs use currentColor:

<x-weather-icon name="rain"
    class="h-8 w-8 text-sky-500 transition-colors hover:text-sky-700" />

If text-* has no effect, the SVG has a hardcoded fill. Fix once in CSS rather than fighting it per-icon:

svg[data-icon] path { fill: currentColor; }

Prefer h-*/w-* classes over passing width/height attributes — it keeps sizing in the same system as the rest of your markup and avoids drift between icon sizes and adjacent text.

Forecast rows and grids

Loop with a stable key and a size="sm" variant:

<div class="grid grid-cols-7 gap-2">
    @foreach ($forecast as $day)
        <div class="flex flex-col items-center gap-1">
            <span class="text-xs text-gray-500">{{ $day->date->format('D') }}</span>
            <x-weather-glyph :code="$day->code" size="sm" :label="$day->summary" />
            <span class="text-sm">{{ $day->high }}°</span>
        </div>
    @endforeach
</div>

For dense grids (multi-city dashboards, hourly strips of 24+ icons), inline SVGs add up. That's a payload decision, not a package decision — see Gotchas.

Emails and PDFs

This is where the package genuinely wins: server-rendered SVG with no external asset reference, no image hosting, no client JS, and it survives mail clients that block remote images. Use the wrapper, pass explicit width/height attributes rather than Tailwind classes (email clients don't have your stylesheet), and inline the color:

<x-weather-glyph code="01d" :label="'Sunny'" width="32" height="32" style="color:#f59e0b" />

Verify against your actual renderer — some PDF engines (DomPDF in particular) handle inline SVG unevenly. If it fails there, fall back to a static PNG for that surface rather than debugging the package.

Testing

Assert on rendered SVG rather than exact markup:

$response = $this->get('/dashboard');
$response->assertOk();
$response->assertSee('<svg', false);
$response->assertSee('aria-label="Sunny"', false);

Keep one test that every value in config('weather.icons') resolves — this catches a typo'd icon name at CI time instead of at render time in production:

public function test_all_mapped_icons_exist(): void
{
    foreach (config('weather.icons') as $code => $icon) {
        $this->blade('<x-weather-icon :name="$name" />', ['name' => $icon])
             ->assertSee('<svg', false);
    }
}

Gotchas and Tips

An unknown icon name throws at render time — a hard 500. This is the single failure mode that reaches customers. <x-weather-icon name="day-sunnyy" /> or a raw provider code passed straight through will blow up the page, not degrade. The wrapper + config allowlist above is the mitigation; treat it as mandatory, not as a nice-to-have refactor you'll do later.

The docs disagree with themselves on the component call syntax. <x-weather-icon name="..." /> vs <x-weather-icon-{name} />. Read the vendor directory and test one call before you build anything on top. Also check whether blade-icons is configured with a shared component that takes name, or per-icon components — that affects how you'd loop icons dynamically.

Class merging is handled by blade-ui-kit/blade-icons, not this package. Passing class="..." merges with whatever the set defines; it doesn't blindly overwrite. Good news, but it means your Tailwind classes are only as predictable as the upstream set's defaults. If an icon looks wrong at one size, check the SVG's own stroke/fill before suspecting your markup.

Cache icon resolution in production. blade-icons ships caching commands; run them in your deploy step alongside view caching:

php artisan icons:cache
php artisan view:cache

Smoke-test under view:cache — component compilation is where a name that worked in dev can surface differently. php artisan view:clear && php artisan icons:clear is your first debugging move when an icon vanishes after deploy.

Watch the constraint direction on 1.8.0. The changelog says "Laravel 13 compatibility," which should mean the illuminate/* range was widened. If it was replaced, teams on Laravel 10–12 get pushed to the 1.7.0 line. Read composer.json, don't infer from the release note. Also check the PHP floor — recent icon-package releases have moved to PHP 8.2+, which is a real blocker on older services. Pin the version in composer.json rather than floating it.

Accessibility is entirely on you. The package emits raw SVGs. Decorative icons need aria-hidden="true" (and focusable="false" for old IE/Edge quirks); meaningful icons need role="img" plus aria-label. The wrapper component is the right place to enforce this — if you leave it to individual templates, some will get it and some won't.

Payload on dense pages. One conditions card: inline SVG is fine. A 24-cell hourly strip or a multi-city grid: inline SVGs bloat HTML meaningfully. Options, cheapest first: curate the subset you actually use and strip the rest; use an SVG sprite with <use> references for grids; or reference an external asset. Rely on view:cache in your production build either way.

You cannot add icons later. The upstream Weather Icons set is stable and effectively archived. "Missing icon" is a permanent coverage gap. Agree a fallback glyph with design up front, and if coverage is a genuine requirement, budget a supplementary set rather than filing a ticket.

Bus factor of one, near-zero adoption. Not disqualifying — the surface area is tiny and the exit is cheap (inline the SVGs into your repo in an afternoon). But keep it shallow: no abstraction layer beyond the one wrapper, no reliance on its release cadence. If it stalls, you delete a dependency and inline some files.

Don't use this for JSON APIs or SPA clients. It's a Blade component. If your frontend consumes JSON, you need the raw SVG set or a JS icon package — this contributes nothing to that surface.

Debugging order when an icon doesn't render: (1) php artisan view:clear and icons:clear; (2) confirm the exact name exists in the vendor SVG directory; (3) try the alternate call syntax; (4) check whether a wrapper is silently passing a null or mismapped code. That sequence covers essentially every failure this package can produce.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource