travelopia/wordpress-blade

Use Laravel Blade components in WordPress.

Maintainers

Package info

github.com/Travelopia/wordpress-blade

Type:wordpress-muplugin

pkg:composer/travelopia/wordpress-blade

Statistics

Installs: 8 427

Dependents: 0

Suggesters: 0

Stars: 7

Open Issues: 0

1.2.1 2026-05-18 21:01 UTC

README

maintenance-status

Use Laravel Blade components in WordPress.

🚨 Note: Only Anonymous Components are currently supported: https://laravel.com/docs/10.x/blade#anonymous-components

Built by the super talented team at Travelopia.

Video Tutorial

▶ ️tutorial

Installation

Install via Composer (recommended):

$ composer require travelopia/wordpress-blade
  • Your composer file should include this
{
	"name": "your/packagename",
	"description": "Description",
	"extra": {
		"installer-paths": {
			"wp-content/mu-plugins/{$name}/": ["type:wordpress-muplugin"]
		}
	},
	"require": {
		"travelopia/wordpress-blade": "^1.0.0",
		"composer/installers": "^2.3"
	},
	"config": {
		"allow-plugins": {
			"composer/installers": true
		}
	},
	"scripts": {
		"wordpress-blade": "wordpress-blade"
	}
}
  • This installs it as an MU Plugin.
  • Then load this plugin in your mu plugins loader file e.g. mu-plugins/loader.php
require_once WPMU_PLUGIN_DIR . '/wordpress-blade/plugin.php';
  • Then require the autoload file from vendor directory by adding the following code in your wp-config.php file.
require_once 'vendor/autoload.php';

Manual Installation (if you know what you are doing):

  1. Download this repository as a ZIP file.
  2. Run composer install --no-dev --optimize-autoloader
  3. Use it either as an MU plugin or a normal plugin!

Building for Production

Compile your Blade components for production as a best practice. Some production environments are read-only, in which case this step is necessary.

Run the following command:

composer exec wordpress-blade -- --config-file=blade.config.php - Ensure the path to the Blade config is correct.

Usage

First, create a blade.config.php file at the root of your project, and add the following code in there:

<?php
/**
 * Blade Config.
 *
 * @package wordpress-blade
 */

define(
	'WORDPRESS_BLADE',
	[
		'paths_to_views'         => [
			__DIR__ . '/wp-content/themes/<your-theme>/<path-to-your-components>',
			'parts' => __DIR__ . '/wp-content/themes/<your-theme>/<path-to-your-components>', // With namespace.
			// Any other paths where Blade needs to look for components.
		],
		'path_to_compiled_views' => __DIR__ . '/wp-content/themes/<your-theme>/dist/blade', // Where you want Blade to save compiled files.
		'never_expire_cache'     => false, // Use `true` on production environments.
		'base_path'              => __DIR__, // The base path that is common to the front-end and admin.
		'encode_echo'            => true, // Double-encode entities in `{{ }}` output. See "Echo encoding" below.
		'register_wp_directives' => true, // Register `@escHtml`, `@escUrl`, `@escAttr`, `@wpKsesPost` directives. See "WordPress-aware escape directives" below.
	]
);

Echo encoding

By default Blade's {{ $value }} calls e( $value, true ), which double-encodes HTML entities. This is the Laravel default and is preserved by setting encode_echo => true.

If your templates receive values that have already been escaped upstream (for example, the output of WordPress's esc_html(), esc_attr(), or wptexturize()), double-encoding turns &amp; into the literal text &amp;amp;. Set encode_echo => false to switch to single-encoding (e( $value, false )) so upstream encoding is preserved.

WordPress-aware escape directives

The package registers four Blade directives that wrap WordPress's escape helpers, letting templates express intent rather than the function call:

Directive Compiles to Use for
@escHtml( $v ) echo esc_html( $v ); Plain text in HTML bodies
@escUrl( $v ) echo esc_url( $v ); href / src attribute values
@escAttr( $v ) echo esc_attr( $v ); Other HTML attribute values
@wpKsesPost( $v ) echo wp_kses_post( $v ); Rich text from editors (block content, ACF WYSIWYG, etc.)

Directive names are prefixed (@esc* / @wp*) so they correlate with the underlying WordPress helper and stay out of Laravel's reserved-directive namespace.

The expression — including its surrounding parentheses — is forwarded verbatim to the underlying WordPress helper. To skip registration (for example, if your project registers its own escape directives), set 'register_wp_directives' => false in the bootstrap config or filter wordpress_blade_register_wp_directives.

Bootstrap a layout.

As a best practice, and if applicable, bootstrap an entire layout like so:

# bootstrap.blade.php
<x-layout>
    <x-hello name="Jane">Hi there!</x-hello>
</x-layout>
# layout.blade.php
@php
    get_header();
@endphp

    <main>
        {{ $slot }}
    </main>

@php
    get_footer();
@endphp
# hello.blade.php
@props( [
    'name' => '',
] )

<div>
    <h1>{{ $slot }}</h1>
    <p>Hello, {{ $name }}</p>
</div>

And then load the view in your template:

Travelopia\Blade\load_view( 'bootstrap' );

You can also load an individual component like so:

$name       = 'hello';              // The name of the component.
$attributes = [ 'name' => 'Jane' ]; // Properties / attributes to pass into the component.
$echo       = true;                 // Whether to echo the component. `false` returns the component as a string.

Travelopia\Blade\load_view( $name, $attributes, $echo );

This is especially useful when you want to load components from Blocks and Full Site Editing.

If you've used namespaces, you can use them like so:

<x-parts::my-part></x-parts::my-part>