WARNING: Development moved into monorepo with demo app. Nette extension composer and npm package will be separated into this one after some polishing.
SEE: Demo app
Modern JavaScript framework integration for Nette using Inertia.js
- 🚀 Support for Vue.js, React, and Svelte
- 🔄 Server-side rendering (SSR) support
- 🛠 Type-safe PHP 8 implementation
- 📦 Easy integration with Nette DI Container
- 🎨 Asset versioning support
- 🔌 Middleware for handling Inertia requests
- 🎯 Custom Latte macros
- PHP 8.1 or higher
- Nette 3.1 or higher
- npm/yarn for frontend dependencies
- Install via Composer(TODO):
composer require paznera/nette-inertia-js
- Register extension in your config.neon:
extensions:
inertia: PaznerA\NetteInertia\InertiaExtension
inertia:
framework: vue # options: vue, react, svelte
ssr: false
rootView: App/Views/Root
version: null # optional - for asset versioning
- Install frontend dependencies based on your chosen framework:
For Vue.js:
npm install @inertiajs/vue3
# or
yarn add @inertiajs/vue3
For React:
npm install @inertiajs/react
# or
yarn add @inertiajs/react
For Svelte:
npm install @inertiajs/svelte
# or
yarn add @inertiajs/svelte
- Create a base presenter:
abstract class BasePresenter extends PaznerA\NetteInertia\InertiaPresenter
{
// Your base presenter logic
}
- Create your root template (App/Views/Root.latte):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My Inertia App</title>
{block head}{/block}
</head>
<body>
{inertia}
{block scripts}{/block}
</body>
</html>
- Set up your frontend entry point (e.g., assets/app.js):
// Vue.js example
import { createApp, h } from 'vue'
import { createInertiaApp } from '@inertiajs/vue3'
createInertiaApp({
resolve: name => {
const pages = import.meta.glob('./Pages/**/*.vue', { eager: true })
return pages[`./Pages/${name}.vue`]
},
setup({ el, App, props, plugin }) {
createApp({ render: () => h(App, props) })
.use(plugin)
.mount(el)
},
})
class HomepagePresenter extends BasePresenter
{
public function renderDefault(): void
{
$this->renderInertia('Homepage/Index', [
'welcome' => 'Hello from Inertia.js!',
'timestamp' => new DateTime(),
]);
}
}
Vue.js example (Pages/Homepage/Index.vue):
<template>
<div>
<h1>{{ $page.props.welcome }}</h1>
<p>Current time: {{ $page.props.timestamp }}</p>
</div>
</template>
<script setup>
defineProps({
welcome: String,
timestamp: String,
})
</script>
Enable SSR in your configuration:
inertia:
ssr: true
# ... other options
Implement version checking for automatic reload on asset changes:
class AssetsVersionProvider
{
public function getVersion(): string
{
return md5_file(WWW_DIR . '/dist/manifest.json');
}
}
inertia:
version: @AssetsVersionProvider::getVersion()
Share data across all components:
class BasePresenter extends InertiaPresenter
{
protected function startup(): void
{
parent::startup();
$this->inertia->share('user', $this->getUser()->isLoggedIn()
? $this->getUser()->getIdentity()->toArray()
: null
);
}
}
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Create a Pull Request
Run tests:
composer test
Run static analysis:
composer phpstan
Run coding standards check:
composer cs-check
TODO: most likely MIT License