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
resources/views/deliveries/show.blade.php. Dots in the view name are converted to directory separators during lookup.
resources/views/deliveries/show.blade.php
courier, passed as the second argument to loadViewsFrom(), forms the contract for both view references and the override directory.
Overrides are resolved per file
Whenview 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.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 renamestrackingCode 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.showcarelessly. - Document the variables you pass, their types, and whether each is required or optional.
- Include the targets of
@includeand@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.
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.
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:cachesucceeds and a fresh boot shows the updated output.
Related pages
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
- Laravel official documentation: Package views
- ServiceProvider: Registering view paths
- FileViewFinder: Lookup order and retained lookup results
- VendorPublishCommand: Conditions for publishing files
- ViewCacheCommand: Collecting view paths and compiling
- ViewClearCommand: Deleting compiled files
- Compiler: Checking modification times