The official React Starter Kit for the Tonka Framework.
Tonka Astro provides a seamless integration between your PHP backend and your React frontend. It comes pre-configured with InertiaJS, DriftQL, and Tonka Router, offering a development experience similar to Laravel's Inertia stack, but optimized for the Tonka ecosystem.
- ⚛️ React + Vite: A modern, blazing-fast frontend environment with Hot Module Replacement (HMR).
- 🚀 InertiaJS: Build single-page applications without building an API. Server-side routing meets client-side rendering.
- 🧠 DriftQL Integration: Access your Elegant ORM models directly in your JSX with the powerful
<Elegant>component. - 🛣️ Tonka Router: Use your backend named routes in your React components effortlessly.
- 🛠️ Zero Config: Out-of-the-box configuration for TypeScript, Tailwind CSS (optional), and build tools.
Install the package via Composer into your Tonka project:
composer create-project tonka/astro astro-appNavigate to the astro-app directory, then run:
npm installThis will scaffold the frontend structure and install NPM dependencies.
Once installed, your resources/js directory is ready to go.
Your React app is automatically wired to your backend via Inertia.
// resources/js/App.tsx
import { usePage } from '@inertiajs/react';
import { route } from 'tonka-router'; // Auto-imported via Spark
export default function App() {
return (
<main>
<h1>Welcome to Tonka Astro</h1>
<a href={route('login')}>Login</a>
</main>
);
}Query your backend database without writing API calls. Use the <Elegant> component to bind data to DOM elements or use Render Props.
import { Elegant } from 'driftql-react';
export default function UserProfile() {
return (
<div>
<h1>My Profile</h1>
{/* Auto-Binding: Fills src automatically from DB */}
<Elegant
as="img"
resource="User"
id={1}
data-src="avatar_url"
className="rounded-full"
/>
{/* Render Props: Full control */}
<Elegant resource="Post" limit={5}>
{(loading, error, posts) => (
loading ? <p>Loading...</p> : (
<ul>
{posts.map(post => <li key={post.id}>{post.title}</li>)}
</ul>
)
)}
</Elegant>
</div>
);
}Navigate using your backend route names. Tonka Router handles URL generation automatically based on your Spark configuration.
import { route, current } from 'tonka-router';
export default function Navbar() {
return (
<nav>
<a href={route('home')}>Home</a>
<a href={route('posts.index')}>Posts</a>
{/* Highlight active link */}
<a href={route('profile')} style={{ color: current().name === 'profile' ? 'blue' : 'black' }}>
Profile
</a>
</nav>
);
}The kit organizes your frontend code cleanly within the Tonka structure:
tonka-project/
├── app/ # Backend Logic (Controllers, Models)
├── resources/
│ ├── js/ # React Frontend (Scaffolded by Astro)
│ │ ├── App.tsx
│ │ ├── Pages/ # Inertia Pages
│ │ └── Components/ # Reusable React Components
│ └── views/ # Twig Templates (for initial load)
├── public/ # Public Assets
└── vite.config.js # Vite Configuration
Located at the root of your project, generated by Astro.
export default {
baseURL: '/api/bridge',
bridge_public_key: 'your-key-here',
// ...
};Configure which routes are visible to the frontend and apply access policies.
return [
'only' => [
['name' => 'home', 'policy' => null],
['name' => 'admin.*', 'policy' => \App\Contracts\DriftQL\AdminPolicy::class],
],
];Start the Vite development server:
npm run devBuild for production:
npm run build- Tonka Framework Docs: Learn about the backend.
- DriftQL Docs: Master the frontend ORM.
- Tonka Router Docs: Understand dynamic routing.
- InertiaJS Docs: Learn the client-side protocol.
MIT