To create a Blade file from the command line in Laravel 13, run php artisan make:view name. Artisan creates resources/views/name.blade.php with a minimal template, and you can use dot notation such as php artisan make:view posts.index to create nested folders in one step. You then return it with view('posts.index').
It is a small command, but it saves switching to the file manager and keeps naming consistent across a team. This guide shows the options, how it fits with layouts and components, and how to change the default content.
Prerequisites
- Laravel 13 with PHP 8.3 or newer. The
make:viewcommand has been part of the framework since Laravel 11. - A terminal in your project root (or
sail artisan/docker compose exec app php artisanif you run Laravel in containers).
Step 1: Create a simple view
php artisan make:view welcome-backThis creates resources/views/welcome-back.blade.php. The generated file contains only a placeholder element, ready for your markup. Render it from a route:
Route::get('/welcome-back', function () {
return view('welcome-back', ['name' => auth()->user()?->name]);
});Step 2: Create nested views with dot notation
Most apps group views by feature. Dots in the name become folders:
php artisan make:view posts.index
php artisan make:view posts.show
php artisan make:view posts.partials.cardThe result is resources/views/posts/index.blade.php, resources/views/posts/show.blade.php and resources/views/posts/partials/card.blade.php. Artisan creates missing folders for you. Reference them the same way in code: view('posts.show', compact('post')) and @include('posts.partials.card').
Because the dot is the folder separator, a folder name must never contain a dot itself.
Step 3: Use the view in a controller
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\View\View;
class PostController extends Controller
{
public function index(): View
{
$posts = Post::query()->latest()->paginate(15);
return view('posts.index', compact('posts'));
}
public function show(Post $post): View
{
return view('posts.show', compact('post'));
}
}Should you create a view, a layout or a component?
Pick the right generator for the job:
- Plain view (
make:view): a page or partial rendered by a route or included in another view. - Anonymous component (
php artisan make:component forms.input --view): a reusable piece of UI with props, stored inresources/views/componentsand used as<x-forms.input />. - Class-based component (
php artisan make:component Alert): the same, plus a PHP class for logic. Use it when the component needs data from the database or complex formatting. - Layout: often an anonymous component such as
resources/views/components/layouts/app.blade.php, used with<x-layouts.app>.
A quick example of a page that uses a component layout:
php artisan make:component layouts.app --view
php artisan make:view dashboard<x-layouts.app>
<h1>Dashboard</h1>
<p>Welcome back, {{ auth()->user()->name }}.</p>
</x-layouts.app>Inside the layout, print {{ $slot }} where the page content should appear.
Step 4: Customise what make:view generates
If every new page should start with your layout, give the command your own stub. make:view first looks for stubs/view.stub in your project root and only falls back to the framework's stub when that file does not exist. The generic php artisan stub:publish command does not copy this particular stub, so create the file yourself:
<x-layouts.app>
<h1>Page title</h1>
</x-layouts.app>Save that as stubs/view.stub. Future make:view runs copy it into each new view. Commit the stubs folder so the whole team gets the same output.
Does make:view create tests?
The command accepts a --test option (and --pest or --phpunit to pick the style) that also generates a feature test for the view. Run php artisan make:view --help to list every option, including --extension for a different file extension. A simple view test can render the view with data and assert that text appears:
<?php
test('the post card shows the title', function () {
$html = view('posts.partials.card', ['title' => 'Hello Laravel'])->render();
expect($html)->toContain('Hello Laravel');
});Common mistakes
- Typing the extension. The command adds
.blade.phpfor you, and the dots in a typed extension are read as folder separators. Pass only the name, such asposts.index. - Using slashes inconsistently. Stick to dot notation in both the command and
view()calls. - Existing file. The command refuses to overwrite a view that already exists unless you pass
--force. Check before forcing. - Stale compiled views. If a change does not show up in production, you probably cached views during deploy. Run
php artisan view:clearor rebuild withphp artisan view:cache.
How do you verify it works?
- Run the command and check the file exists under
resources/views. - Call
View::exists('posts.index')in Tinker; it should returntrue. - Visit the route and confirm the content renders without a "View not found" error.
How should you organise view folders?
A layout that scales well is one folder per feature, named after the resource: posts, orders, settings. Inside each, keep the page views (index, show, create, edit) at the top level and small pieces in a partials subfolder. Shared UI such as buttons, inputs and modals belongs in components, not partials, because components accept props and slots. Using make:view with consistent dot names keeps that structure without anyone having to remember it.
Mail templates follow the same idea: keep them under resources/views/mail so they never mix with page views.
FAQ
Which Laravel version added make:view?
It shipped with Laravel 11 and is available in Laravel 12 and 13.
Can I create several views at once?
The command takes one name per run. A short shell loop, or several commands in a row, does the job.
Where do package views go?
Packages load views from their own folder with a namespace, used as view('package::name'). To override one, publish it into resources/views/vendor.



