Currently Available: Need a skilled Software Developer for your next project?
Categories
Laravel

Shipping Views and Assets in Laravel Packages

Laravel package maintainers need to make two kinds of files available to an application. Laravel renders views on the server. Browsers request static files such as CSS, JavaScript, and images. Laravel can render views directly from the package directory. Maintainers publish copies when users need to customize views or serve assets from the application’s public directory.

A service provider is a package class that registers resources with Laravel. These examples follow Laravel 13’s package-development conventions. They show how to register a view namespace, let users override views, publish assets for browsers, and explain the commands and checks users need.

Load package views through a namespace

In the service provider’s boot method, call loadViewsFrom to tell Laravel where the package’s views are stored. The namespace gives application code a consistent name for referring to those views.

public function boot(): void
{
    $this->loadViewsFrom(__DIR__.'/../resources/views', 'courier');
}

After registering the views, package code can render resources/views/dashboard.blade.php like this:

return view('courier::dashboard');

The view namespace, courier here, is part of the package’s public interface. Keep it consistent and document it; it does not have to match the package’s Composer vendor and package name. Laravel’s package-development documentation describes registering package resources through a service provider.

Laravel checks the application’s resources/views/vendor/courier directory before falling back to the package’s own view directory. Users can override a package view by placing a file at the matching relative path under that application directory. For example, resources/views/vendor/courier/dashboard.blade.php overrides the package’s dashboard view. This lookup behavior is documented in Laravel’s package view guidance.

If users should be able to copy views into the application with Artisan, Laravel’s command-line tool, register a separate publishing group:

$this->publishes([
    __DIR__.'/../resources/views' => resource_path('views/vendor/courier'),
], 'courier-views');

Publishing creates a copy owned by the application. Laravel does not need that copy to render the package’s original view. Tell users which views they can override, where to put each copy, and how the namespace and relative path match. Laravel continues to use an override instead of the package view, so users should compare customized files with newer package versions when upgrading.

Publish assets to the public directory

The browser needs a URL for a file in the application’s public web directory. Register a source-to-destination mapping in the provider to let users copy package assets there:

$this->publishes([
    __DIR__.'/../public' => public_path('vendor/courier'),
], 'courier-assets');

If the package contains public/css/app.css, the mapping places it at public/vendor/courier/css/app.css. A Laravel Blade template, Laravel’s view-template format, can generate the file’s URL with the asset() helper:

The helper generates a URL; it does not copy the package file. Users must publish the asset before the browser can retrieve it from the configured public path. Laravel documents asset() and the ASSET_URL setting, which supports serving asset URLs from a separate host or content delivery network.

Give assets and views distinct, package-specific tags so users can publish only the files they want:

php artisan vendor:publish --tag=courier-assets
php artisan vendor:publish --tag=courier-views

Laravel also supports publishing resources registered by a particular provider:

php artisan vendor:publish --provider="Vendor\Courier\CourierServiceProvider"

Document the exact tag or provider class alongside each command. A broad tag such as public is another supported option, but a package-specific tag makes the intended files clearer when an application has multiple packages with publishable resources.

Explain provider registration and updates

Laravel can register a package’s service provider automatically through package discovery. The package must list the provider in the extra.laravel.providers section of its composer.json. An application can disable discovery for a package. In that case, someone must register the provider manually. Otherwise, Laravel does not run its boot method, and the package’s view namespace and publishing mappings are unavailable. Include the provider class and manual registration instructions in installation troubleshooting. Laravel describes provider discovery and package resources.

When a user reports a missing view, have them check that the provider loaded, the view call uses the registered namespace, and the file exists at the expected relative path under the package’s view directory. For missing CSS or JavaScript, have them check that they ran the documented asset command and that the file exists under the mapped public destination. The URL should refer to that public path, rather than to the package’s filesystem location under vendor.

Tell users what happens when an update changes a published asset: they must publish it again to copy the new version. Laravel’s --force option lets them overwrite existing files, including files they edited in the destination directory. Explain when to use the option and warn users to save their custom changes before running it. Keep shipped assets separate from files users are expected to customize so they can see which files an overwrite will affect.

Laravel’s service-provider methods cover these conventions. Maintainers who want a higher-level API can use a helper such as Spatie Laravel Package Tools, which adds its own conventions for registering views and assets.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

Your email address will not be published. Required fields are marked *