Favicon ToolsVerifyBuild
Framework

Laravel Favicon Generator

Laravel has no icon convention of its own. Files in public/ are served at the site root, and the link tags belong in your Blade layout's head. Getting the web server's document root wrong is the most common reason a perfectly placed favicon.ico still 404s.

public/ is the web root

In a correctly configured Laravel app the web server's document root is the public/ directory, not the project root. That means public/favicon.ico is requested as /favicon.ico, and anything you put next to artisan is not URL-addressable at all.

The tags themselves live in the Blade layout most pages extend, typically resources/views/layouts/app.blade.php or the welcome view if you have not built a layout yet. Vite bundles CSS and JS; it does not invent favicon tags for you.

Where the files go

  • my-laravel-app/
    • public/document root
      • favicon.icoadd
      • favicon-32x32.pngadd
      • apple-touch-icon.pngadd180x180
      • icon-192.pngadd
      • icon-512.pngadd
      • site.webmanifestadd
      • index.php
    • resources/
      • views/
        • layouts/
          • app.blade.phplink tags go here
    • vite.config.js

Keep icons in public/ with stable names. Putting them under resources/ and hashing them with Vite is optional cache-busting, not the default path.

Blade layout head

{{-- resources/views/layouts/app.blade.php --}}
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>{{ config('app.name') }}</title>

  <link rel="icon" href="{{ asset('favicon.ico') }}" sizes="any">
  <link rel="icon" type="image/png" sizes="32x32" href="{{ asset('favicon-32x32.png') }}">
  <link rel="apple-touch-icon" href="{{ asset('apple-touch-icon.png') }}">
  <link rel="manifest" href="{{ asset('site.webmanifest') }}">

  @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>

asset() prefixes the configured asset URL, which matters when the app is not served from the domain root. Hardcoding /favicon.ico skips that.

public/ vs Vite-processed icons

ApproachUse whenTrade-off
Files in public/Almost every appStable URLs; bust cache by renaming
Vite::asset(...) from resources/You already version images through ViteHashed filenames; more moving parts
No link tags, only public/favicon.icoQuick local checkMisses PNG, apple-touch-icon, manifest

Laravel favicon FAQ

Do I need to rebuild Vite after changing the favicon?

Not if the files live in public/ and you referenced them with asset(). Vite only needs a rebuild when the icons are part of its input graph via Vite::asset or an imported URL in CSS/JS.

The tab still shows the old Laravel icon.

Browsers cache favicons aggressively. Confirm the published HTML points at your file, then load the site in a private window. If you replaced public/favicon.ico in place, rename it (favicon-v2.ico) or hard-refresh once so the URL itself changes.

Where does the default favicon come from?

Laravel's skeleton ships a favicon.ico in public/. Replace that file and add the rest of the set beside it. Nothing in the framework regenerates it on deploy.

Related platforms