88
Using Vite with Inertia — Laravel, *React* & Tailwind
I rely on this post:
I tried to follow it with React as well, and having failed as you will see in this comment, I share with you the process and the solution.
First I also followed this tutorial - 5 parts:
First - Immediately after creating a new laravel project, package.json
should be modified
so:
{
"private": true,
"scripts": {
"dev": "vite",
"production": "vite build"
},
"devDependencies": {
"axios": "^0.24.0",
"lodash": "^4.17.21",
"vite": "^2.7.9",
"autoprefixer": "^10.4.0",
"postcss": "^8.4.5",
"tailwindcss": "^3.0.7",
"@inertiajs/inertia": "^0.10.1",
"@inertiajs/inertia-react": "^0.7.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"@inertiajs/progress": "^0.2.6"
"@vitejs/plugin-react": "^1.1.3"
}
}
Add a tailwind.config.js
file and a postcss.config.js
file
//tailwind.config.js
module.exports = {
content: [
"./resources/**/*.blade.php",
"./resources/**/*.jsx",
"./resources/**/*.js",
],
theme: {
extend: {},
},
plugins: [],
}
//postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
add file vite.config.js
// vite.config.js
import react from '@vitejs/plugin-react';
export default ({ command }) => ({
base: command === 'serve' ? '' : '/build/',
publicDir: 'fake_dir_so_nothing_gets_copied',
build: {
manifest: true,
outDir: 'public/build',
rollupOptions: {
input: 'resources/js/app.js',
},
},
plugins: [
react(),
//add blade plugin to reload page on change blade files
{
name: 'blade',
handleHotUpdate({ file, server }) {
if (file.endsWith('.blade.php')) {
server.ws.send({
type: 'full-reload',
path: '*',
});
}
},
}
],
});
add to resources/css/app.css
@tailwind base;
@tailwind components;
@tailwind utilities;
change resources/js/app.js
file
Do not try to use JSX components The file is JS and compilation will fail.
The truth is at first I tried like that
render(App({...props}), el)
It caused this error
/*This file is not JSX so VITE will not automatically inject the React import*/
import React from 'react'
import {render} from 'react-dom'
import {createInertiaApp} from '@inertiajs/inertia-react'
import '../css/app.css';//import the app css
createInertiaApp({
resolve: async (name) => {
return (await import(`./Pages/${name}`)).default
},
setup({el, App, props}) {
render(React.createElement(App, props), el)
},
})
Excellent, now just need to take care of bringing the files to the app.blade.php
add Helpers/vite.php
file ( make the Helpers directory )
<?php
use Illuminate\Support\Facades\Http;
use Illuminate\Support\HtmlString;
function vite_assets(): HtmlString
{
$devServerIsRunning = false;
if (app()->environment('local')) {
try {
Http::get("http://localhost:3000");
$devServerIsRunning = true;
} catch (Exception) {
}
}
if ($devServerIsRunning) {
return new HtmlString(<<<HTML
<script type="module">
import RefreshRuntime from "http://localhost:3000/@react-refresh"
RefreshRuntime.injectIntoGlobalHook(window)
window.\$RefreshReg$ = () => {}
window.\$RefreshSig$ = () => (type) => type
window.__vite_plugin_react_preamble_installed__ = true
</script>
<script type="module" src="http://localhost:3000/@vite/client"></script>
<script type="module" src="http://localhost:3000/resources/js/app.js"></script>
HTML);
}
$manifest = json_decode(file_get_contents(
public_path('build/manifest.json')
), true);
return new HtmlString(<<<HTML
<script type="module" src="/build/{$manifest['resources/js/app.js']['file']}"></script>
<link rel="stylesheet" href="/build/{$manifest['resources/js/app.js']['css'][0]}">
HTML);
}
add function to app.blade.php
head
<!-- Scripts -->
{ vite_assets() }}
Add autoload to the new file you just created
include it to composer.json
"autoload": {
"psr-4": {
...
},
"files": [
"app/Helpers/vite.php"
]
},
Just a few runs at the terminal:
to autoload file
composer dump-autoload
require the inetria to server side
composer require inertiajs/inertia-laravel
install npm packages
npm install
That is!
from now on redirect routers to Inertia::render
as shown here
88