This project demonstrates how to integrate InertiaJS with Mojolicious, using Svelte as the frontend framework. It implements a complete InertiaJS adapter for Mojolicious and provides a working example application.
Clone and Setup
git clone <repository-url>
cd inertia-mojo
./script/setup.sh
Start Development Server
./script/dev.sh
Visit the Application
inertia-mojo/
โโโ lib/
โ โโโ InertiaTest.pm # Main application class
โ โโโ InertiaTest/Controller/ # Controllers
โ โ โโโ Example.pm # Basic pages and forms
โ โ โโโ Users.pm # CRUD example
โ โโโ Mojolicious/Plugin/
โ โโโ Inertia.pm # InertiaJS plugin
โโโ client/ # Frontend (Svelte)
โ โโโ src/
โ โ โโโ app.js # Inertia app entry point
โ โ โโโ app.css # Global styles
โ โ โโโ Pages/ # Svelte page components
โ โ โโโ Shared/ # Shared components
โ โโโ package.json # Node dependencies
โ โโโ vite.config.js # Build configuration
โโโ templates/
โ โโโ inertia/app.html.ep # Root HTML template
โโโ public/dist/ # Built assets
โโโ script/ # Development scripts
โโโ t/ # Tests
โโโ cpanfile # Perl dependencies
# In your Mojolicious app
$self->plugin('Inertia' => {
version => sub { '1.0.0' },
shared => {
auth => sub ($c) { $c->session('user') }
}
});
# In your controller
$c->inertia('ComponentName', { prop1 => 'value1' });
# Main rendering helper
$c->inertia('Users/Index', { users => \@users });
# Share data across requests
$c->inertia_share(flash => 'Success!');
# Handle redirects
$c->inertia_location('/dashboard');
# Optional props for expensive data
$c->inertia('Dashboard', {
stats => $c->inertia_optional(sub { expensive_query() })
});
# Version management
$c->inertia_version('abc123');
$app->plugin('Inertia' => {
# Asset version (for cache busting)
version => sub ($c) {
return $c->_read_manifest_version() || time();
},
# Shared data (available to all responses)
shared => {
auth => sub ($c) {
return { user => $c->session('user') };
},
csrf_token => sub ($c) { $c->csrf_token },
},
# Root view template
root_view => 'inertia/app',
# Manifest file location
manifest_path => 'public/dist/.vite/manifest.json',
});
Run the test suite:
carton exec -- prove -l t/
Run with verbose output:
carton exec -- prove -lv t/
The application includes several demonstration pages:
/
) - Welcome page with basic information/about
) - Technology overview/users
) - Complete CRUD example/forms
) - Form validation demo<script>
import Layout from '../Shared/Layout.svelte'
import { useForm } from '@inertiajs/svelte'
export let users = []
let form = useForm({
name: '',
email: ''
})
function submit() {
$form.post('/users')
}
</script>
<Layout>
<h1>Users</h1>
<!-- Your component content -->
</Layout>
sub index ($self) {
my @users = $self->app->db->select('users')->hashes;
$self->inertia('Users/Index', {
users => \@users,
can => {
create => $self->can_create_users,
edit => $self->can_edit_users,
}
});
}
# Perl dependencies
carton install
# Node.js dependencies
cd client && npm install
cd client
npm run build # Production build
npm run dev # Development server
carton exec -- prove -l t/
Install dependencies
carton install --deployment
cd client && npm ci
Build assets
cd client && npm run build
Start application
carton exec -- ./app.pl daemon -l http://*:8080
"Can't locate Mojo/Base.pm"
carton install
"Vite dev server not detected"
cd client && npm run dev
Assets not loading
public/dist/
contains built assetscd client && npm run build
Set environment variable for detailed logging:
MOJO_LOG_LEVEL=debug ./script/dev.sh
This project is provided as a demonstration and educational resource.