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

Assets Laravel Package

digitallyhappy/assets

A Laravel package for managing front-end assets in one place. Register CSS and JavaScript files from controllers, views, or service providers, then render them in your layouts with a simple Blade directive—keeping asset inclusion organized and consistent.

View on GitHub
Deep Wiki
Context7

Getting Started

digitallyhappy/assets is the asset manager behind Backpack for Laravel, but it is framework-agnostic enough to use in any Blade app: you point it at a CSS/JS file (local path or CDN URL), and it takes care of emitting the right <link>/<script> tag — serving a cached, hash-versioned copy in production and the original file in development.

Install

composer require digitallyhappy/assets:^2.1

Version 2.1.0 is the first release with Laravel 10 support. If your composer.json pins ^2.0, Composer will happily resolve 2.0.4 on a Laravel 10 app and then fail on framework constraints — bump the constraint rather than fighting --ignore-platform-reqs.

The service provider and Basset facade are auto-discovered; there is nothing to register in config/app.php.

Publish the config and look at it first

php artisan vendor:publish --provider="DigitallyHappy\Assets\AssetsServiceProvider" --tag=config

config/basset.php is where the package's behaviour actually lives: dev-mode flag, where cached files are written, and how they're named. Read it before writing any Blade — most "why is this file 404ing" questions are answered there.

First use case

Take a hardcoded tag in resources/views/layouts/app.blade.php:

<link rel="stylesheet" href="{{ asset('css/app.css') }}">

and replace it with:

@basset('css/app.css')
@basset('https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css')

Then set BASSET_DEV_MODE=true in .env locally and false in production. Locally you load the original file (so edits show up instantly); in production Basset copies the file into a public cache folder and serves it with a fingerprint so browsers can cache it forever.

Implementation Patterns

Layout partial, not the layout itself. Keep every @basset call in one place — e.g. resources/views/inc/assets.blade.php — and @include it from the layout. When a designer asks "where does this script come from", there's exactly one answer.

Per-page assets via Blade stacks. This is where Basset earns its keep in a component/widget codebase. A view pulls in its own dependencies without the layout knowing about them:

@push('after_styles')
    @basset('vendor/flatpickr/flatpickr.min.css')
@endpush

@push('after_scripts')
    @basset('vendor/flatpickr/flatpickr.min.js')
    @bassetBlock('booking-datepicker')
        <script>flatpickr('.datepicker', { minDate: 'today' });</script>
    @endBassetBlock
@endpush

@bassetBlock('unique-key') … @endBassetBlock wraps inline code so it gets hashed and cached like a real file — useful for widget init snippets you don't want inlined on every page load. The key must be globally unique.

Registering assets from PHP. The Basset facade works outside Blade: Basset::script($path), Basset::style($path), Basset::add($path). Use it from a View Composer or a service provider to conditionally register, say, a map library only on pages that render a map — that keeps your layout free of @if (Route::is(...)) branches.

Mixing CDN and local files. Absolute URLs pass through as-is; local paths get copied and fingerprinted. Both go through the same directive, so you can migrate a CDN asset to a self-hosted one by changing a single string.

Deployment. The public cache folder is generated, not committed. Run the package's cache command as part of deploy (check php artisan list | grep basset for the exact names in your version — typically a build/refresh and a clear command), after config:cache, and make sure the folder is writable by the web user. Committing the generated folder is a legitimate alternative if your deploys have no post-deploy hook.

Tests. Force dev mode off (or the cache path to a temp dir) in phpunit.xml so tests don't write into public/; assertions on markup are then stable.

Gotchas and Tips

  • Laravel 10 needs ^2.1. On a fresh Laravel 10 upgrade, the failure mode is a constraint conflict in composer update, not a runtime error. Bump the requirement in the same commit as the framework upgrade.
  • Dev mode is the #1 source of "works locally, breaks in production." With BASSET_DEV_MODE=true, the raw source path is emitted; with it off, the cached path is emitted. If the cached copy was never generated on the server, you get a 404 that only exists in production. Verify by viewing source: cached assets show up under the configured cache prefix (/basset/... by default) with a hash in the filename.
  • Config caching bites. BASSET_DEV_MODE read through config() is frozen by php artisan config:cache. If flipping the env var does nothing, run php artisan config:clear.
  • Stale fingerprints. Fingerprints are derived from file contents/paths, and the cached copy lives on disk independently of your repo. After changing an asset, clear the Basset cache as part of the deploy (or the build step won't refresh). Symptom: your CSS edit appears locally but not on staging.
  • Duplicated @bassetBlock keys silently serve the wrong script — the second block with the same identifier wins or gets skipped depending on order. Namespace keys like booking-datepicker rather than scripts.
  • Stack ordering matters. @basset inside @push('after_scripts') lands wherever @stack('after_scripts') sits in the layout. If a script depends on jQuery or on Basset's own output, echo that stack after the layout's base assets.
  • Don't double-load. If you already use Vite for app.js, either Vite owns the bundle or Basset does — running both over the same entry point gives you two copies and confusing order-of-execution bugs.
  • Permissions. The cache folder must be writable by the user running the deploy and readable by the web server. On shared hosting, a sudo-created folder is a classic silent break.
  • Extension points are thin on purpose: the config file and the Basset facade. For anything bespoke (custom attributes on the emitted tags, a different cache strategy), wrap @basset in your own Blade directive or a small helper class rather than patching vendor code — you'll want the next minor to install cleanly.
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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
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