The unofficial Inertia.js server-side adapter for WordPress.
Option 1: Install the package via composer. (Recommended)
composer require boxybird/inertia-wordpress
Option 2: Clone or download as a plugin and run composer install
before activating in WordPress Admin.
- Demo: https://wp-inertia.andrewrhyand.com
- Theme: https://github.com/boxybird/wordpress-inertia-demo-theme
- Links: https://inertiajs.com/links
- Pages: https://inertiajs.com/pages
- Requests: https://inertiajs.com/requests
- Shared Data: https://inertiajs.com/shared-data
- Asset Versioning: https://inertiajs.com/asset-versioning
- Partial Reloads: https://inertiajs.com/partial-reloads
Location: /wp-content/themes/your-theme/app.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<?php wp_head(); ?>
</head>
<body>
<?php bb_inject_inertia(); ?> // Adds Inertia to the page
<?php wp_footer(); ?>
</body>
</html>
Location: /wp-content/themes/your-theme/functions.php
By default the WordPress adapter will use the app.php
from .../your-theme/app.php
. If you would like to use a different file name, you can change it. E.g. .../your-theme/layout.php
.
<?php
add_action('init', function () {
Inertia::setRootView('layout.php');
});
By default the bb_inject_inertia()
function returns <div id="app" data-page="{...inertiaJsonData}"></div>
. If you need to override the div
id, you can.
// Override 'id="app"' to 'id="my_app"' and add classes
<?php bb_inject_inertia('my_app', 'bg-blue-100 font-mono p-4'); ?>
Location: /wp-content/themes/your-theme/index.php
<?php
use BoxyBird\Inertia\Inertia;
global $wp_query;
Inertia::render('Index', [
'posts' => $wp_query->posts,
]);
Location: /wp-content/themes/your-theme/index.php
This may look busy, however it can be thought of as a "Controller". It gives you a place to handle all your business logic. Leaving your Javacript files easier to reason about.
<?php
use BoxyBird\Inertia\Inertia;
global $wp_query;
// Build $posts array
$posts = array_map(function ($post) {
return [
'id' => $post->ID,
'title' => get_the_title($post->ID),
'link' => get_the_permalink($post->ID),
'image' => get_the_post_thumbnail_url($post->ID),
'content' => apply_filters('the_content', get_the_content(null, false, $post->ID)),
];
}, $wp_query->posts);
// Build $pagination array
$current_page = isset($wp_query->query['paged']) ? (int) $wp_query->query['paged'] : 1;
$prev_page = $current_page > 1 ? $current_page - 1 : false;
$next_page = $current_page + 1;
$pagination = [
'prev_page' => $prev_page,
'next_page' => $next_page,
'current_page' => $current_page,
'total_pages' => $wp_query->max_num_pages,
'total_posts' => (int) $wp_query->found_posts,
];
// Return Inertia view with data
Inertia::render('Posts/Index', [
'posts' => $posts,
'pagination' => $pagination,
]);
You may be wondering what this moster line above does:
'content' => apply_filters('the_content', get_the_content(null, false, $post->ID));
Because we can't use the WordPress function the_content()
outside of a traditional theme template setup, we need to use get_the_content()
instead. However, we first need to apply the filters other plugins and WordPress have registered.
Matter of fact, we can't use any WordPress function that uses echo
, and not return
.
But don't fret. WordPress typically offers a solution to this caveat: get_the_title()
vs the_title()
, get_the_ID()
vs the_ID()
, and so on...
Reference: https://developer.wordpress.org/reference/functions/
Location: /wp-content/themes/your-theme/functions.php
add_action('init', function () {
// Synchronously using key/value
Inertia::share('site_name', get_bloginfo('name'));
// Synchronously using array
Inertia::share([
'primary_menu' => array_map(function ($menu_item) {
return [
'id' => $menu_item->ID,
'link' => $menu_item->url,
'name' => $menu_item->title,
];
}, wp_get_nav_menu_items('Primary Menu'))
]);
// Lazily using key/callback
Inertia::share('auth', function () {
if (is_user_logged_in()) {
return [
'user' => wp_get_current_user()
];
}
});
// Lazily on partial reloads
Inertia::share('auth', Inertia::lazy(function () {
if (is_user_logged_in()) {
return [
'user' => wp_get_current_user()
];
}
}));
// Multiple values
Inertia::share([
// Synchronously
'site' => [
'name' => get_bloginfo('name'),
'description'=> get_bloginfo('description'),
],
// Lazily
'auth' => function () {
if (is_user_logged_in()) {
return [
'user' => wp_get_current_user()
];
}
}
]);
});
Location: /wp-content/themes/your-theme/functions.php
Optional, but helps with cache busting.
add_action('init', function () {
// If you're using Laravel Mix, you can
// use the mix-manifest.json for this.
$version = md5_file(get_stylesheet_directory() . '/mix-manifest.json');
Inertia::version($version);
});
inertia-wordpress's People
Forkers
gkiokan furiosojack codwelt codeinwordpress saas786 zunz anoblet patlamontagne thinkryan carlos-widgilabs adiraoco madafina jefsev alexstewartja hdytsgt tofandel mattpurland carlosalbertocruz web-id-fr davgit clausreiser alexcavender ynamite santoe alexwenger billylighterinertia-wordpress's Issues
This is awesome
Just wanted to say this is awesome. Came across this looking for a way to integrate WP and Inhertia after playing with it on a Laravel setup. I'm very excited about this approach in concept. Looks like it's been a bit stalled since May, curious if you have future plans?
DOMContentLoaded eventListener is needed for createInertiaApp to work
Hi there,
I did install the plugin to create a wordpress theme using inertia, react and typescript but I was facing an issue with inertia that couldn't get the "app" element. I don't know why but placing the createInertiaApp() function in an event listener fixed it.
The problem is that the element with id 'app' doesn't exist when the function is called in app.js which is strange because it looks like it work in your theme exemple using vuejs. I never used laravel-mix before so it might be the reason it fails.
Here is a repository to see the problem : https://github.com/Tanguy-Plf/wordpress-inertia
you'll need to install the polylang plugin and go to http://localhost:10018/es/ to see the bug in the console.
The fix is commented bellow in app.tsx
Thank you for your help!
How to work with woocommerce?
Gutenberg
Hi, any idea how to get this to work with Gutenberg?
Im working with timber and advanced custom fields to load custom blocks, These are Just twig files which can be injected with vue components as well.
I will give it a try asap :-)
Reponses are opening in modal in production
Hi there,
Somehow cached responses are showed in a modal.
When i activate SpinupWP (nginx caching plugin from my wordpress hosting environment) or cache-enabler, strange things happens. Some windows / links are opening in a modal, some not.
As Reinink says in #inertiajs/inertia#586
This is what happens when you don't return an Inertia response from the <inertia-link> endpoint. All Inertia requests MUST return an Inertia response, otherwise they are shown in a modal like this. This is core to how the library works. π
When Logged in the no-cache is added to the headers, no modal is opened
I thought maybe the 'no-cache, must-revalidate, max-age=0'
Has this todo with the inertia-wordpress adapter or is this default inertia behaviour?
Support for Inertia::lazy()
Hello,
I'm building a framework on top of your adapter and inertia. I'd like to know if you have any plan to add the Inertia::lazy method to the adapter ? Here is the PR on the official adapter for laravel: inertiajs/inertia-laravel#175
And the commit : inertiajs/inertia-laravel@53ebf77
Would be great to have that feature on wordpress,
Have a nice week-end
Composer support
Hi there, first of all thanks for your amazing work !
I've seen you added the type="wordpress-plugin" in the composer.json
on master so we can use composer to get the plugin, that's cool !
However, the plugin still expect use to run composer install
inside the plugin :
Any idea how to fix this ?
Thanks !
Create a composer package instead of a wordpress plugin
Since i already need to run a composer install within the plugin's directoy of the wordpress-inertia-plugin,
I think it's more likely to a add the wordpress-inertia adapter within my theme files, with composer.
Just like the timber v2 installation
https://timber.github.io/docs/v2/installation/
If there is an inertia update, i can check the composer file within my theme.
Or your starter theme.
Form handling
Hello, thanks for this awsome adapeter!
I have been using this plugin to create full webpage and have simple contact form that needs to submit data to WordPress and return errors if any.
On Frontend I did create Form helper and on WordPress I did create Rest route. My issue was, that this plugin doesn't document how to use Inertia.js form with Wordpress and I did need a quite a lot of research and debugging to get this working.
Now I have solution to handle errors in Inertia.js as it's required in their docs.
So my question - is possible to integrate or maybe document form use case in plugin?
I was not sure if I should include code snippets, but here you go.
Wordpress code for handling rest route
/**
* Handle form
*
* @param \WP_REST_Request $request The request.
*/
public function handle_contact_form( \WP_REST_Request $request ) {
$data = $request->get_params();
// Validate the data.
$rules = [
'first_name' => [ 'required' ],
'email' => [ 'required', 'email' ],
];
$v = new \Valitron\Validator( $data );
$v->mapFieldsRules( $rules );
// If validation fails, store errors in session and redirect back to the previous page.
if ( ! $v->validate() ) {
$_SESSION['errors'] = $v->errors();
wp_redirect( wp_get_referer() );
exit;
}
// Code to save data in WP...
// Redirect back.
wp_redirect( wp_get_referer() );
exit;
}
Code for WP session
if ( ! session_id() ) {
session_start();
}
Frontend code for Svelte
<script>
import { useForm, page } from '@inertiajs/svelte';
const form = useForm({
first_name: '',
email: '',
});
function handleSubmit() {
$form.clearErrors();
// Rest endpoint in WP
const url = $page.props.ajax_url + '/contacts';
$form.post(url, {
preserveScroll: true,
onSuccess: () => {
$form.reset();
},
});
}
<script>
<form on:submit|preventDefault={handleSubmit}>
<div>
<label for="cf-fist-name">Fist name</label>
<input id="cf-fist-name" type="text" bind:value={$form.first_name} />
{#if $form.errors.first_name}
<span class="error">{$form.errors.first_name}</span>
{/if}
</div>
<div>
<label for="cf-email">Email</label>
<input id="cf-email" type="email" bind:value={$form.email} />
{#if $form.errors.email}
<span class="error">{$form.errors.email}</span>
{/if}
</div>
<button type="submit">Submit</button>
</form>
External Redirect Support
The official documentation provides a method for returning a location redirect which is not implemented here.
This is very useful when handling redirects to error pages.
return Inertia::location($url);
Inertia requests are not detected when the site is under a DNS proxy
I went ahead a made a PR fixing this bug.
Custom query vars
Hi there,
Meanwhile my first wordpress-intertia project is in progress.
However, I'm trying to create filters in my archive page.
function custom_query_vars_filter($vars) {
$vars[] = 'testing';
return $vars;
}
add_filter( 'query_vars', 'custom_query_vars_filter' );
What happens, with your inertia-wordpress example theme when i visit:
http://inertia.local/movies/?testing=myvar i got a 301 redirected
When i add the post_type and custom query to a default 'twentynineteen'
http://inertia.local/movies/?testing=myvar it's giving me the proper movies archive page + the testing query var
I could write a custom rest controller for now, but just using the inertia-link would be ideal
<inertia-link href="/filmography" :data="{ filters: 'editorial' }">Editorial Work</inertia-link>
Future releases?
Hello,
Are there going to be any releases in the near future I noticed that in other adapters there are recent commits?
What is your view on this?
Best regards.
Support for SSR
Dear author,
Is there a way to support SSR, since most WordPress websites need SEO friendly?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.