Skip to main content
A package that lets users customize screen or mail templates needs more than a way to publish views. It also needs a contract that allows updates while published files stay in place. Fixing a Blade file in the package does not guarantee that the consuming application is rendering that file. This page builds on Laravel Package Development and treats view selection, file publishing, and caching as separate concerns. The official documentation references Laravel 13, and framework references point to the latest release, v13.34.0.

Registering and publishing are separate steps

loadViewsFrom() registers a search path for a namespace. publishes() registers a source and destination, and the actual copy is performed by vendor:publish. In the following example, courier::deliveries.show is available even without publishing.
src/CourierServiceProvider.php
Place the package file at resources/views/deliveries/show.blade.php. Dots in the view name are converted to directory separators during lookup.
resources/views/deliveries/show.blade.php
The view namespace is separate from the Composer package name and the PHP namespace. Here, courier, passed as the second argument to loadViewsFrom(), forms the contract for both view references and the override directory.

Overrides are resolved per file

When view is resolved, ServiceProvider::loadViewsFrom() checks each entry in the view.paths config in order. If a path contains a vendor/courier directory, that directory is added to the namespace, and the package path is added last. FileViewFinder searches the namespace’s paths in order and returns the first file it finds. With the standard resources/views setup, the order is as follows. This is not a switch for the whole directory. If a user overrides only deliveries/show.blade.php, every other view that was not overridden is still loaded from the package.
When view.paths has multiple entries, there can be multiple override locations. resource_path('views/vendor/courier') is the publish destination in this example, not something that pins lookup to that location alone. Use a package-specific namespace, and avoid designs where multiple providers add paths to the same name.

Customize only the views you need

Users can copy the templates with the following command. Specify the provider and tag so other resources are not pulled in.
This registration publishes the entire view directory. If users do not need to override everything, they can review the contents and keep only the files they customize, or manually copy just the files they need to the same relative paths. This matters because any copy that exists is treated as an override, even if it was never edited.
Published templates are not automatically synchronized with package updates. If an outdated copy takes priority, fixing only the package’s version will not change that view. Display bug fixes and form changes also need to be compared against the override files.

Republishing does not merge changes

VendorPublishCommand normally skips the copy when a destination file with the same name already exists. --force overwrites existing files. --existing is also an option that “overwrites files that have already been published,” not a mode that preserves user edits. None of these perform a merge that compares the old version, the new version, and the user’s edits. They also do not automatically remove views from the destination that were deleted from the package. Do not reduce your update procedure to “just republish the same tag.”

Maintain views as a public API

Beyond view names, the data a view receives and the parts it references also affect user customizations. For example, if a new version renames trackingCode to a different variable, users who kept the old template can no longer receive the value they need from the new code. Before a release, check the following contracts.
  • Do not change the namespace or view names such as deliveries.show carelessly.
  • Document the variables you pass, their types, and whether each is required or optional.
  • Include the targets of @include and @extends, as well as Blade component props, in your list of changes.
  • List the views you changed, and the changes that should be applied to previously published copies, in the release notes.
For users, provide a procedure for comparing the old and new package views and manually bringing the necessary changes into their customized files. Files that no longer need to be overridden can be removed to fall back to the package’s views, after preserving any changes through backups or version control.

The Blade cache does not update override files

view:cache precompiles Blade templates into PHP. ViewCacheCommand first runs view:clear, then collects the regular view paths and the paths registered for namespaces to find the templates to compile.
This process does not rewrite published Blade files, nor does it change view lookup priority. If an outdated override file exists, it will still be selected after the cache is rebuilt. During deployment, finish updating the code and override files before compiling. If you want to delete the compiled files and re-render during development, use the following command.
When normal timestamp checking is enabled, the Blade compiler compares the modification times of the source file and the compiled file. However, some setups disable timestamp checking, so do not rely solely on automatic detection for rebuilds at deploy time.

Distinguish this from cached lookup results

FileViewFinder::find() stores the paths it finds in the $views array of that Finder instance. In addition, the existence of override directories is checked in the loadViewsFrom() callback. Adding a new directory after boot does not automatically add it to the already registered search paths. view:clear is not a command that wipes the Finder state held by other running processes. For long-running processes such as Octane, reload them according to your normal deployment procedure. The Finder’s flush() clears lookup results, but it does not register new override directories.

Checks before release

In addition to the package’s tests, verify the following combinations in a consuming application. Tests that only render the latest templates cannot verify compatibility for users who published an older version.
  • With nothing published, the package’s views are rendered.
  • Overriding a single file gives priority to that file only, and the rest fall back to the package.
  • With the old version’s published templates still in place, the views render with the data the new version passes.
  • A normal republish preserves customizations, and the addition of unpublished files behaves as intended.
  • After changing an override file, view:cache succeeds and a fresh boot shows the updated output.

Views

Review the basics of creating views, passing data, and precompiling.

Blade Templates

Review how to use layouts, includes, and components.

Version Compatibility Management

Tie template contract changes to your release policy.

Octane

Review the lifecycle and reloading of long-running applications.

Primary sources

Last modified on October 4, 2026