Frontend Development
Imba
By default Formidable uses Imba for its frontend development. You can build your frontend either as a single-page application or as a web application.
Multi-page Application
To build a multi-page application, use the create-formidable
CLI with the following flags:
npx create-formidable@latest example-app --imba --scaffolding mpa
This will create a new project with mpa related files.
See the Views documentation for more information.
Single-page Application
To build a single-page application, you can use the create-formidable
CLI with the following flag:
npx create-formidable@latest example-app --imba
This will create a new project and install the @formidablejs/view
package, then publish spa related files.
The frontend files will be published in the resources/frontend
folder.
To get started, open the resources/frontend/App.imba
file.
See the Views documentation for more information.
Vue.js, React & Svelte
Formidable provides an Inertia Adapter through Laravel Mix.
Laravel Mix is a package developed by Laracasts creator Jeffrey Way. It provides a fluent API for defining webpack build steps for your Laravel and Formidable applications using several common CSS, TypeScript and JavaScript pre-processors.
In other words, Mix makes it a cinch to compile and minify your application's CSS, TypeScript and JavaScript files. Through simple method chaining, you can fluently define your asset pipeline. For example:
mix.ts('resources/js/app.ts', 'public/js')
.postCss('resources/css/app.css', 'public/css');
Installation & Setup
To get started with an application powered by Inertia, use the following commands:
Vue
npx create-formidable@latest example-app --vue
React
npx create-formidable@latest example-app --react
Svelte
npx create-formidable@latest example-app --svelte
This will scaffold a Vuejs, React or Svelte application for you.
Running Mix
Mix is a configuration layer on top of webpack, so to run your Mix tasks you only need to execute one of the NPM scripts that are included in the default Formidable package.json
file. When you run the dev
or production
scripts, all of your application's CSS, TypeScript and JavaScript assets will be compiled and placed in your application's public
directory:
- npm
- pnpm
- yarn
- bun
// Run all Mix tasks...
npm run mix:dev
// Run all Mix tasks and minify output...
npm run mix:prod
// Run all Mix tasks...
pnpm run mix:dev
// Run all Mix tasks and minify output...
pnpm run mix:prod
// Run all Mix tasks...
yarn mix:dev
// Run all Mix tasks and minify output...
yarn mix:prod
// Run all Mix tasks...
bun mix:dev
// Run all Mix tasks and minify output...
bun mix:prod
Watching Assets For Changes
The mix:watch
script will continue running in your terminal and watch all relevant CSS, TypeScript and JavaScript files for changes. Webpack will automatically recompile your assets when it detects a change to one of these files:
- npm
- pnpm
- yarn
- bun
npm run mix:watch
pnpm run mix:watch
yarn mix:watch
bun mix:watch
You don't have to run the mix:watch
script, running node craftsman serve --dev
will also watch your assets for changes and recompile them when needed.
Component Rendering
Creating responses
In your controller, provide both the name of the TypeScript or JavaScript page component, as well as any props (data) for the page.
In this example we're passing a single prop, called post
to the Post/Show page component:
- Imba
- TypeScript
import { @use } from '@formidablejs/framework'
import { Inertia } from '@formidablejs/inertia'
import { PostRepository } from '../../Repositories/PostRepository'
import { Controller } from './Controller'
export class PostController < Controller
@use(PostRepository)
def show post\Promise<Post>
post = await post
Inertia.render('Post/Show', {
post: post
})
import { use } from '@formidablejs/framework'
import { Inertia } from '@formidablejs/inertia'
import { InertiaResponse } from '@formidablejs/inertia'
import { PostRepository } from '../../Repositories/PostRepository'
import { Controller } from './Controller'
export class PostController extends Controller
@use(PostRepository)
async show(post: Promise<Post>): Promise<InertiaResponse> {
post = await post
return Inertia.render('Post/Show', {
post: post
})
}
}
We can access the post
prop in our page component like so:
- Vue
- React
- Svelte
<script lang="ts" setup>
defineProps({
post: {
type: Post,
required: true
}
})
</script>
<template>
<h1>{{ post.title }}</h1>
<p>{{ post.body }}</p>
</template>
export default function Show({ post }: { post: Post }) {
return (
<>
<h1>{post.title}</h1>
<p>{post.body}</p>
</>
)
}
<script>
/** @type {Post} post */
export let post
</script>
<h1>{post.title}</h1>
<p>{post.body}</p>
Root template data
The default inertia root view is defined in the config/inertia.imba
or config/inertia.ts
config file:
- Imba
- TypeScript
import { App } from '../resources/views/app'
export default {
# --------------------------------------------------------------------------
# Root View
# --------------------------------------------------------------------------
#
# Sets the root template that's loaded on the first page visit.
rootView: App
# --------------------------------------------------------------------------
# Laravel Mix Command
# --------------------------------------------------------------------------
#
# Command that runs to execute Laravel Mix when Formidable is in development
# mode.
mix: "npm run mix:watch" # "pnpm run mix:watch" || "yarn mix:watch" || "bun mix:watch"
}
import { App } from '../resources/views/app'
export default {
/*
* --------------------------------------------------------------------------
* Root View
* --------------------------------------------------------------------------
*
* Sets the root template that's loaded on the first page visit.
*/
rootView: App,
/**
* --------------------------------------------------------------------------
* Laravel Mix Command
* --------------------------------------------------------------------------
* Command that runs to execute Laravel Mix when Formidable is in development
* mode.
*/
mix: "npm run mix:watch" // "pnpm run mix:watch" || "yarn mix:watch"
}
If you'd like to provide a custom root for for a specific component, you may do so by using setRootView
:
- Imba
- TypeScript
Inertia.render('Welcome').setRootView(CustomFormidableView)
Inertia.render('Welcome').setRootView(CustomFormidableView)
You can also pass data props to a root view by using withViewData
:
- Imba
- TypeScript
Inertia.render('Welcome').withViewData({
meta: meta
})
Inertia.render('Welcome').withViewData({
meta: meta
})
This section is incomplete. Join our discord if you have questions.
For more information on how to use Laravel Mix and Inertia, see the Laravel Mix documentation and the Inertia documentation.
TailwindCSS
You can use TailwindCSS with your React or Vue application. In this guide, we will setup TailwindCSS for your application.
Installation
Install tailwindcss and its peer dependencies via npm, and create your tailwind.config.js file:
- npm
- pnpm
- yarn
- bun
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init
pnpm install -D tailwindcss postcss autoprefixer
pnpm exec tailwindcss init
yarn add -D tailwindcss postcss autoprefixer
yarn exec tailwindcss init
bun add --dev tailwindcss postcss autoprefixer
bunx tailwindcss init
Configuration
In your webpack.mix.js
file, add tailwindcss as a PostCSS plugin:
.postCss('resources/css/app.css', './public/css', [
require("tailwindcss"),
])
Add the paths to all of your template files in your tailwind.config.js
file:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./resources/**/*.js",
"./resources/**/*.ts",
"./resources/**/*.tsx",
"./resources/**/*.vue",
"./resources/**/*.svelte",
],
theme: {
extend: {},
},
plugins: [],
}
Add the @tailwind directives for each of Tailwind’s layers to your ./resources/css/app.css
file:
@tailwind base;
@tailwind components;
@tailwind utilities;
You're done! Visit https://tailwindcss.com/ for more information.