Install Amalgam into your project using Composer:
composer require dakin/amalgamNext, add the following lines to your resources/js/app.js file. Amalgam will compile all scripts extracted from your Blade files here.
The preamble bit is required for the React stuff.
import '@vitejs/plugin-react/preamble';
import 'virtual:amalgam';Finally, update your vite.config.js to register Amalgam and the React plugin:
import {
defineConfig
} from 'vite';
import laravel from 'laravel-vite-plugin';
import tailwindcss from "@tailwindcss/vite";
+ import react from '@vitejs/plugin-react';
+ import amalgam from './vendor/dakin/amalgam/dist/vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: ['resources/css/app.css', 'resources/js/app.js'],
refresh: true,
}),
tailwindcss(),
+ amalgam(),
],
server: {
cors: true,
},
});When ready, start your Vite development server:
npm run devAmalgam is intended to be used within Blade components. Create one in resources/views/components. You can use the following Acorn command:
wp acorn make:view components.alertThen add a <script editor type="jsx"> tag.
This is where you'll do any JS actions. This supports React, but you can also do vanilla JS stuff here. Amalgam’s Vite plugin will scan all Blade files within your resources/views directory, extract code from <script editor> tags and bundle it into a single JavaScript file. The script tags will never actually be rendered on the page.
<script editor>
console.log('My vanilla JS')
</script>
<!-- A more complicated example using React -->
<script editor type="jsx">
import { PanelBody } from '@wordpress/components';
import { InspectorControls } from '@wordpress/block-editor';
document.addEventListener('DOMContentLoaded', function () {
wp.blocks.getBlockType('my/block').edit = function ({attributes, setAttributes}) {
return (<AdditionalEditContent blockName="my/block">
<InspectorControls>
<PanelBody title="Custom Panel">
<p>This sidebar panel is being rendered based on the content within a blade template!</p>
</PanelBody>
</InspectorControls>
</AdditionalEditContent>)
}
})
</script>Important
Since the code will get extracted into a JavaScript file, you cannot use Blade within the script tag.
Since Amalgam compiles <script editor> tags with Vite, you can use any import supported in a JavaScript/TypeScript file:
<script editor>
// NPM module
import { twMerge } from 'tailwind-merge'
// Local file
import { createTodo } from '@/todo'
// Raw file content
import check from '@resources/img/icons/check.svg?raw'
// Types
import type { TodoItem } from '@/types'
</script>The @ alias points to resources/js by default. You can customize the aliases in your vite.config.js file.
Make sure to always import types using the import type syntax to avoid issues.
To use React in your Amalgam project:
- Install the React plugin:
npm install --save-dev @vitejs/plugin-react- Add the React plugin before the amalgam plugin in your
vite.config.js:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';
import amalgam from './vendor/dakin/amalgam/dist/vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: ['resources/css/app.css', 'resources/js/app.js'],
refresh: true,
}),
react(), // React plugin MUST come before amalgam
amalgam(),
],
});Important: The React plugin must be configured before the amalgam plugin so it can process the
.tsxvirtual modules that Amalgam generates.
- Regular scripts (
<script editor>): Processed as vanilla JavaScript - React scripts (
<script editor type="react">): Processed as JSX/TypeScript
React scripts are compiled to separate .tsx modules. You have full control over component registration and WordPress integration.
Amalgam uses TypeScript to provide a terse syntax for props and also to power the IDE features. However, it disables the strict mode by default. This means you are not forced to use types. You can write regular JavaScript without getting type errors, but still get autocomplete and type hints in your IDE.
Options for both enabling strict mode and fully opting out of TypeScript will be available in the future.