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

Laravel Mime Type Icons Laravel Package

creode/laravel-mime-type-icons

Laravel package that maps MIME types to icons, making it easy to display the right file-type icon for uploads, attachments, and media across your app. Provides simple helpers to resolve an icon from a MIME type or file, so file lists and previews stay visually consistent with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

The package is small and single-purpose: it maps a MIME type (and usually an extension) to an icon identifier you can drop into a Blade view. Treat the source as the documentation — at 0 stars and a single Feb-2024 release, the README may lag the code.

  1. composer require creode/laravel-mime-type-icons — then pin it ("creode/laravel-mime-type-icons": "1.0.*" or the exact tag) so a silent patch can't change icon output across your UI.
  2. Confirm package discovery picked it up: php artisan about or look for the provider in bootstrap/cache/packages.php. If it isn't auto-discovered, register the provider (and any Facade alias) in config/app.php.
  3. Open vendor/creode/laravel-mime-type-icons/src/ before writing any code. You need three answers up front:
    • What does the return value look like — a Font Awesome class (fa-file-pdf), a bare name (pdf), or an SVG/blob?
    • Is the mapping exposed via a Facade, a helper function, or a Blade component?
    • Is there a publishable config? php artisan vendor:publish --provider="Creode\MimeTypeIcons\...ServiceProvider" (check the publishes() call for the correct tag).
  4. First use case: a documents/attachments table. You almost certainly already store a mime_type column — feed it in and render.
{{-- shape will vary; check the actual API --}}
<i class="{{ MimeTypeIcons::get($attachment->mime_type) }}"></i>
{{ $attachment->original_name }}

If your CSS pipeline doesn't already ship the icon set the package assumes (Font Awesome is the common bet), resolve that before you wire it into ten views — otherwise every icon renders as a blank box and you'll blame the package.

Implementation Patterns

Wrap it, don't sprinkle it. The package is unmaintained-by-popularity; the cost of replacing it later is trivial if it's behind one seam and painful if it's inlined in 40 Blade files.

{{-- resources/views/components/file-icon.blade.php --}}
@props(['type' => null, 'size' => 'w-5 h-5'])
<i {{ $attributes->merge(['class' => $size.' '.(MimeTypeIcons::get($type) ?? 'fa-file')]) }}></i>

Now a fork, a config override, or a switch to your own SVG sprite is a one-file change.

Store the MIME type at upload time, never derive it per row. For files on S3 or any remote disk, calling Storage::mimeType($path) inside a @foreach turns a listing page into N network round-trips. Capture it once in the upload handler and persist it as a column.

$path = $request->file('document')->store('documents');
Document::create([
    'path'      => $path,
    'mime_type' => $request->file('document')->getMimeType(), // server-side, not getClientMimeType()
]);

Expose the icon from your API layer, not the frontend. If a Vue/React/Inertia front end renders the file list, add an icon key in the JsonResource so the mapping lives in one place:

public function toArray($request): array
{
    return [
        'name'      => $this->original_name,
        'mime_type' => $this->mime_type,
        'icon'      => MimeTypeIcons::get($this->mime_type),
    ];
}

Group by category where the package supports it. If the API exposes something like isImage() / isDocument() / a category string, use it for filtering chips and for choosing preview behaviour (<img> for images, icon for everything else) rather than re-parsing str_starts_with($mime, 'image/') yourself.

Cover the fallback explicitly. A private unknown/generic icon should be a deliberate, testable branch, not whatever the package returns for null. Add a feature test that asserts the icon for your three or four most common uploads plus one nonsense MIME.

Upload previews / Livewire. With Livewire\TemporaryUploadedFile, call getMimeType() on the stored file after upload, or ->getMimeType() on the temporary file — the client-supplied type is unreliable for previews of .heic, .svg, and anything Office.

Gotchas and Tips

Audit the mapping against your own data before trusting it. The mapping table is the package — that's the entire value proposition. Run SELECT mime_type, COUNT(*) FROM files GROUP BY 1 ORDER BY 2 DESC and check every top-20 type resolves to something sensible. The failure modes are boring and universal: .docx vs .doc, application/zip vs application/x-zip-compressed, text/csv vs application/csv vs text/plain, image/svg+xml, and the application/octet-stream bucket that swallows everything Windows uploads.

getClientMimeType() lies. It reports what the browser claimed. Use getMimeType() (symfony/mime-guessed) — or, better, MimeType::from($file->getRealPath()) — for anything you'll show to a user or gate access on.

Config caching bites on deploy. If you publish and edit the mapping, php artisan config:cache must be in your deploy script. If the provider reads config in its constructor rather than lazily, even that won't help — check the source. Symptom: correct locally, all-generic icons in production.

Version and framework support are unverified. With one release from Feb 2024 and zero dependents, confirm the require constraints in its composer.json cover your PHP and illuminate/support versions. If it predates your Laravel major, it may still work (it's a lookup table) but you'll get dependency-resolution noise.

Fork-or-vendor is a legitimate answer. ~200 lines of array plus a helper. If the mapping is thin, publish the config and append your own entries there; if the API is wrong for you, copy the file into app/Support/ and delete the dependency. Both are cheaper than waiting for a maintainer who may not exist.

Escape if it emits SVG. If the package returns markup, {!! !!} on a value derived from a user-supplied MIME type is an XSS vector. Prefer an API that returns a class name; if it returns SVG path data, render inside a <svg> with a fixed viewBox you control.

Don't assert exact HTML in tests. If you snapshot the rendered icon, adding a class breaks the suite. Assert assertSee('fa-file-pdf') or assert against the component's computed value, not the full tag.

Debugging is one line: php artisan tinker --execute="dump(app(\Creode\MimeTypeIcons\...::class)->get('application/pdf'));" — if that resolves, the package is fine and your problem is CSS, config cache, or a null MIME.

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.
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk