Introduction

Getting Started

An opinionated Prettier plugin for Laravel Blade templates.

#Installation

Requires Node.js 18 or newer.

Install Prettier and the plugin in your project:

1npm i -D prettier prettier-plugin-blade@^3

Optional integrations:

1npm i -D @prettier/plugin-php prettier-plugin-tailwindcss

#Migration

Chisel v3 (prettier-plugin-blade) is a ground-up rewrite. Expect output changes compared to previous versions.

If you rely on previous versions, you should specify the exact version you'd like to use in your package.json.

#Quick Start

Create or update your .prettierrc:

1{
2 "plugins": [
3 "prettier-plugin-blade"
4 ],
5 "overrides": [
6 {
7 "files": ["*.blade.php"],
8 "options": {
9 "parser": "blade"
10 }
11 }
12 ]
13}

Format:

1npx prettier --write "resources/views/**/*.blade.php"

#CLI Flags

You can pass Blade plugin options directly to the Prettier CLI as kebab-case flags:

1npx prettier "resources/views/**/*.blade.php" \
2 --write \
3 --plugin prettier-plugin-blade \
4 --plugin @prettier/plugin-php \
5 --parser blade \
6 --blade-php-formatting safe \
7 --blade-php-formatting-targets echo \
8 --blade-php-formatting-targets directiveArgs \
9 --blade-component-prefixes x \
10 --blade-component-prefixes flux \
11 --blade-directive-arg-spacing space \
12 --blade-echo-spacing tight

Notes:

  • Use kebab-case in CLI flags (for example bladePhpFormatting -> --blade-php-formatting).
  • Load @prettier/plugin-php when using bladePhpFormatting: "safe" from the CLI.
  • Array options use repeated flags in CLI (for example: --blade-inline-intent-elements p --blade-inline-intent-elements svg --blade-inline-intent-elements svg:*).
  • bladeDirectiveCaseMap takes a JSON object string when passed via CLI, but shell quoting is easy to get wrong. Prefer setting it in .prettierrc.

#PHP Formatting

To format embedded PHP fragments inside Blade, install @prettier/plugin-php and include it in plugins:

1{
2 "plugins": [
3 "prettier-plugin-blade",
4 "@prettier/plugin-php"
5 ],
6 "overrides": [
7 {
8 "files": ["*.blade.php"],
9 "options": {
10 "parser": "blade",
11 "bladePhpFormatting": "safe"
12 }
13 }
14 ]
15}

Notes:

  • Without @prettier/plugin-php, the formatter still works. It falls back gracefully and leaves PHP fragments unchanged.
  • bladePhpFormatting modes documented here: "off", "safe".

#Enable Tailwind CSS Class Sorting

Install the Tailwind CSS plugin and include it in plugins:

1{
2 "plugins": [
3 "prettier-plugin-blade",
4 "prettier-plugin-tailwindcss"
5 ],
6 "overrides": [
7 {
8 "files": ["*.blade.php"],
9 "options": {
10 "parser": "blade"
11 }
12 }
13 ]
14}

#VS Code Setup

  1. Install the Prettier - Code formatter extension (esbenp.prettier-vscode).
  2. Ensure your project has local devDependencies for Prettier and this plugin.
  3. Add workspace settings in .vscode/settings.json:
1{
2 "editor.formatOnSave": true,
3 "editor.defaultFormatter": "esbenp.prettier-vscode",
4 "prettier.requireConfig": true,
5 "files.associations": {
6 "*.blade.php": "blade"
7 },
8 "[blade]": {
9 "editor.defaultFormatter": "esbenp.prettier-vscode"
10 }
11}

#Options

#Blade Plugin Options

Option Type Default Values
bladePhpFormatting choice "safe" "off", "safe", "aggressive"
bladePhpFormattingTargets string[] ["directiveArgs", "echo", "phpBlock", "phpTag"] echo, directiveArgs, phpBlock, phpTag; use [] (or CLI none) to disable all
bladeSyntaxPlugins string[] ["statamic"] plugin names (for example ["statamic"])
bladeDirectiveCase choice "preserve" "preserve", "canonical", "lower"
bladeDirectiveCaseMap string "" JSON object string, e.g. {"disk":"Disk"}
bladeDirectiveArgSpacing choice "space" "preserve", "none", "space"
bladeDirectiveBlockStyle choice "preserve" "preserve", "inline-if-short", "multiline"
bladeBlankLinesAroundDirectives choice "preserve" "preserve", "always"
bladeEchoSpacing choice "preserve" "preserve", "space", "tight"
bladeSlotClosingTag choice "canonical" "canonical", "preserve"
bladeInlineIntentElements string[] ["p", "svg", "svg:*"] elements and namespace wildcards
bladeComponentPrefixes string[] ["x", "s", "statamic", "flux", "livewire", "native"] component prefixes
bladeInsertOptionalClosingTags boolean false true, false
bladeKeepHeadAndBodyAtRoot boolean true true, false

bladePhpFormattingTargets aliases supported in each array entry:

  • echoes -> echo
  • directive-args, directive_args -> directiveArgs
  • php-block, php_block -> phpBlock
  • php-tag, php_tag -> phpTag

bladeComponentPrefixes behavior:

  • Bare prefix tokens expand to both Blade component separator forms:
    • x -> x-, x:
    • widget -> widget-, widget:
  • Explicit separator tokens are preserved as-is:
    • x- matches only dash form tags
    • x: matches only colon form tags

bladeInlineIntentElements SVG behavior:

  • svg keeps single-line <svg>...</svg> container intent when the source is inline.
  • svg:* keeps inline attribute and style intent for SVG namespace elements such as <path> and <line>.
  • Remove one or both entries to opt out of those SVG-specific inline layouts.

#bladeBlankLinesAroundDirectives

This option controls blank lines between directive branches inside a structured directive block.

Examples of branch separators this option affects:

  • @if ... @else ... @endif
  • @switch ... @case ... @default ... @endswitch
  • @section ... @endsection

Primary scope:

  • It decides how much vertical space to print between one branch and the next branch marker.
  • In preserve mode it can also keep some existing blank lines between structured siblings inside a directive body when those blank lines were already present in source.

That means it can affect spacing before @else, @elseif, @endif, @case, @default, @endswitch, and similar closers/openers inside the same directive block.

Supported values:

  • "preserve"
    • Keeps an existing blank line between directive branches if one existed in the source.
    • Otherwise prints a single newline between branches.
  • "always"
    • Always inserts a blank line between directive branches.
    • In practice this means two line breaks between branches.

Example input:

1@if($x)
2<p>a</p>
3@else
4<p>b</p>
5@endif

With bladeBlankLinesAroundDirectives: "preserve":

1@if ($x)
2 <p>a</p>
3@else
4 <p>b</p>
5@endif

With bladeBlankLinesAroundDirectives: "always":

1@if ($x)
2 <p>a</p>
3
4@else
5 <p>b</p>
6
7@endif

Notes:

  • This option is most visible when directive blocks print in multiline form.
  • If a block is kept inline, there are no multiline branch separators for this option to manage.
  • In preserve mode, some authored blank lines inside a directive body can also survive between structured siblings when the source already had them.

#Relevant Core Prettier Options

This plugin also respects standard Prettier options, including:

  • printWidth
  • tabWidth
  • useTabs
  • singleQuote
  • singleAttributePerLine
  • bracketSameLine
  • endOfLine
  • htmlWhitespaceSensitivity

#Example Full Config

1{
2 "plugins": [
3 "prettier-plugin-blade",
4 "@prettier/plugin-php",
5 "prettier-plugin-tailwindcss"
6 ],
7 "overrides": [
8 {
9 "files": ["*.blade.php"],
10 "options": {
11 "parser": "blade",
12 "htmlWhitespaceSensitivity": "css",
13 "bladePhpFormatting": "safe",
14 "bladePhpFormattingTargets": ["directiveArgs", "echo", "phpBlock", "phpTag"],
15 "bladeSyntaxPlugins": ["statamic"],
16 "bladeDirectiveCase": "preserve",
17 "bladeDirectiveArgSpacing": "space",
18 "bladeDirectiveBlockStyle": "preserve",
19 "bladeBlankLinesAroundDirectives": "preserve",
20 "bladeEchoSpacing": "space",
21 "bladeSlotClosingTag": "canonical",
22 "bladeInlineIntentElements": ["p", "svg", "svg:*"],
23 "bladeComponentPrefixes": ["x", "s", "statamic", "flux", "livewire", "native"],
24 "bladeInsertOptionalClosingTags": false,
25 "bladeKeepHeadAndBodyAtRoot": true
26 }
27 }
28 ]
29}

#Troubleshooting

#Tailwind CSS classes are not sorting

  • Confirm prettier-plugin-tailwindcss is installed.
  • Confirm it is listed in plugins.
  • Confirm class values are static strings (not mixed with Blade interpolation).

#PHP formatting is not running

  • Install @prettier/plugin-php.
  • Set bladePhpFormatting to "safe".
  • Ensure target is enabled in bladePhpFormattingTargets.

#VS Code formats with wrong Prettier

  • Use local project dependencies.
  • Set "prettier.requireConfig": true.
  • Set "prettier.prettierPath" when needed.