VueForm Laravel is a powerful, production-ready PHP form builder that integrates VueForm's reactive UI components with Laravel's backend validation. Create beautiful, responsive forms entirely in PHP without writing JavaScript code. Perfect for Laravel developers who want modern form interfaces with Material Design themes.
Key Benefits:
- β Zero JavaScript Required - Build forms in pure PHP
- β Laravel Integration - Native validation, routing, and security
- β Material Design UI - Professional, responsive forms
- β Theme Support - Multiple themes including dark mode
- β Production Ready - Optimized assets and performance
- β Developer Friendly - Easy to learn, extensive documentation
π Full Documentation | π Quick Start | π¨ Themes
- Why VueForm Laravel?
- Key Features
- Requirements
- Installation
- Quick Start Guide
- Themes
- Configuration
- Creating Form Components
- Rendering Forms
- Form Submission Handling
- Advanced Usage
- Performance Optimization
- Troubleshooting
- Contributing
- License
VueForm Laravel bridges the gap between Laravel's powerful backend and modern frontend form experiences. As a PHP developer, you can now create interactive, validated forms without learning Vue.js or managing complex frontend build processes.
Perfect for:
- Laravel developers building admin panels
- PHP developers creating user registration forms
- Teams needing consistent form styling across applications
- Projects requiring rapid form development
- Applications with complex validation requirements
What makes it special:
- Server-Side First: Define forms in PHP with Laravel validation
- Client-Side Enhancement: Automatic Vue 3 reactivity and Material Design
- Zero Configuration: Works out-of-the-box with Laravel
- SEO Friendly: Server-rendered forms with JavaScript enhancement
- Accessible: WCAG compliant form components
- Reusable Form - Anywhere in your
.blade.phpfile you can use this form - Laravel Validation Integration - Use familiar validation rules directly in form definitions
- Dynamic Routing - Automatic endpoint generation based on Laravel routes
- Text Inputs - Text, email, password, textarea, URL, number
- Selection Controls - Radio, checkbox, select, multiselect, toggle
- Date & Time - Date picker, time picker, datetime picker
- File Uploads - Single/multiple file upload with preview
- Rich Content - WYSIWYG editor, markdown editor
- Dynamic Lists - Repeatable field groups with add/remove
- Layout Elements - Groups, columns, tabs, steps
- PHP: 8.0 or higher
- Laravel: 9.x, 10.x, or 11.x
- Composer: 2.x or higher
- Browser Support: Modern browsers (Chrome, Firefox, Safari, Edge)
Note: This package works with Laravel's default frontend setup. No Vue CLI, Vite, or npm installation required on your endβall frontend assets are pre-bundled.
composer require bijoy4067/vueform-laravelphp artisan vendor:publish --tag=vueform-laravel --forceThis command publishes:
- Configuration file to
config/vueform-laravel.php - Pre-compiled CSS and JavaScript assets to your
publicdirectory - Stubs for form component generation
Add the following to your main Blade layout's <head> section (typically resources/views/layouts/app.blade.php):
<head>
<!-- Required: CSRF Token for AJAX submissions -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<!-- Load VueForm Laravel Assets (CSS + JS) -->
{{ VueFormLaravel\Abstracts\VueFormBuilder::loadAssets() }}
<!-- Your other head elements -->
</head>What this does: Loads pre-compiled Vue 3 components, VueForm library, and Material Theme styles. No build process needed.
php artisan vueform:make ContactFormThis creates app/VueForm/ContactForm.php with boilerplate code.
Open app/VueForm/ContactForm.php and add your form fields:
<?php
namespace App\VueForm;
use VueFormLaravel\Abstracts\VueFormBuilder;
use VueFormLaravel\Elements\Fields\TextElement;
use VueFormLaravel\Elements\Fields\TextareaElement;
use VueFormLaravel\Elements\Static\ButtonElement;
use VueFormLaravel\Elements\Vueform;
class ContactForm extends VueFormBuilder
{
protected function buildForm()
{
return Vueform::build()
->schema([
TextElement::name('name')
->label('Your Name')
->rules('required|min:3'),
TextElement::name('email')
->label('Email Address')
->rules('required|email'),
TextareaElement::name('message')
->label('Message')
->rules('required|min:10'),
ButtonElement::submitButton('Send Message')
]);
}
public static function validatedFormData($request)
{
// This receives only validated data
// Send email, save to database, etc.
return response()->json([
'message' => 'Thank you! We received your message.'
]);
}
}<?php
namespace App\Http\Controllers;
use App\VueForm\ContactForm;
class ContactController extends Controller
{
public function show()
{
return view('contact', [
'contactForm' => app(ContactForm::class)
]);
}
}<!-- resources/views/contact.blade.php -->
@extends('layouts.app')
@section('content')
<div class="container">
<h1>Contact Us</h1>
{!! $contactForm->render() !!}
</div>
@endsectionThat's it! Navigate to your route and see a fully functional, validated contact form with Material Design styling.
VueForm Laravel supports multiple themes for different visual styles and user preferences. Themes are configured in config/vueform-laravel.php and automatically generate separate CSS/JS bundles for optimal performance.
- Default Theme - Clean Material Design with light background
- Dark Theme - Dark mode optimized for low-light environments
- Custom Themes - Create your own themes by extending configuration
// config/vueform-laravel.php
'themes' => [
'default' => [
'--vf-primary' => '#6200ee',
'--vf-bg-input' => '#ffffff',
// ... more variables
],
'dark' => [
'--vf-primary' => '#BB86FC',
'--vf-bg-input' => '#1E1E1E',
// ... dark theme variables
],
],Set the current theme in your controller or middleware:
session(['theme' => 'dark']);The form will automatically load the appropriate theme assets and styling.
The main configuration file is located at config/vueform-laravel.php. Here you can customize:
- Themes: Define multiple themes with CSS variables
- Validation Messages: Customize error messages
- File Upload Settings: Configure upload paths and validation
- API Endpoints: Set custom endpoints for dynamic options
// config/vueform-laravel.php
'themes' => [
'default' => [
'--vf-primary' => '#6200ee',
'--vf-danger' => '#B00020',
'--vf-success' => '#4CAF50',
'--vf-font-size' => '1rem',
// ... hundreds of customizable variables
],
],# Google reCAPTCHA (optional)
GOOGLE_RECAPTCHA_SITE_KEY=your_site_key_here
GOOGLE_RECAPTCHA_SECRET_KEY=your_secret_key_here // Spacing
'--vf-gutter' => '1rem',
'--vf-min-height-input' => '2.375rem',
// State colors
'--vf-color-success' => '#10b981',
'--vf-color-danger' => '#ef4444',
]
];
After updating configuration, **clear your browser cache** or do a hard refresh (Ctrl+F5) to see changes.
---
## ποΈ Creating Form Components
### Using the Artisan Command
```bash
# Basic form
php artisan vueform:make UserRegistrationForm
# Form in a subdirectory
php artisan vueform:make Admin/UserEditForm
# With custom namespace
php artisan vueform:make Forms/Checkout/PaymentForm
Forms are created in app/VueForm/ by default. You can organize them in subdirectories.
Every form component extends VueFormBuilder and implements buildForm():
<?php
namespace App\VueForm;
use VueFormLaravel\Abstracts\VueFormBuilder;
use VueFormLaravel\Elements\Vueform;
class ExampleForm extends VueFormBuilder
{
// Optional: Custom submission endpoint
protected static $actionUrl = null; // Auto-generated if null
// Optional: HTTP method (GET, POST, PUT, PATCH, DELETE)
protected static $method = 'POST';
// Required: Define form structure
protected function buildForm()
{
return Vueform::build()
->schema([
// Your form elements here
]);
}
// Optional: Handle form submission
public static function validatedFormData($request)
{
// Process validated data
// $request contains only fields that passed validation
return response()->json(['success' => true]);
}
// Alternative: Manual validation
public static function formData($request)
{
// Manually validate
$validated = $request->validate([
'field_name' => 'required|string|max:255'
]);
// Process data
return response()->json(['success' => true]);
}
}- Auto-Generated Endpoints: If
$actionUrlisnull, the package generates a secure route automatically - Validation Methods:
validatedFormData()- Receives pre-validated data based on element rulesformData()- Receives raw request for manual validation
- Response Format: Return JSON responses for AJAX forms
Best for: Multi-page applications, forms with complex logic
// Controller
public function create()
{
return view('users.create', [
'userForm' => app(\App\VueForm\UserForm::class)
]);
}<!-- View -->
{!! $userForm->render() !!}Best for: Simple forms, prototyping, global components
<!-- Anywhere in any Blade file -->
{!! (new \App\VueForm\NewsletterForm())->render() !!}The package validates form data based on rules defined in your elements:
protected function buildForm()
{
return Vueform::build()
->schema([
TextElement::name('username')
->rules('required|alpha_dash|min:3|max:20|unique:users'),
TextElement::name('email')
->rules('required|email|unique:users'),
TextElement::name('age')
->rules('nullable|integer|min:13|max:120')
]);
}
public static function validatedFormData($request)
{
// All rules passed, $request contains clean data
User::create($request->all());
return response()->json([
'message' => 'User created successfully!',
'redirect' => route('users.index')
]);
}TextElement::name('email')
->rules('required|email')
->messages([
'required' => 'We need your email to contact you.',
'email' => 'Please enter a valid email address.'
]);Errors are automatically displayed below each field. Customize error display:
return Vueform::build()
->displayErrors(true) // Show/hide error messages
->validateOn('change|submit') // When to validate
->schema([...]);public static function validatedFormData($request)
{
// Example: Create database record
$user = User::create($request->only(['name', 'email']));
// Example: Send email
Mail::to($user)->send(new WelcomeEmail($user));
// Example: Fire event
event(new UserRegistered($user));
// Return success response
return response()->json([
'message' => 'Registration complete!',
'redirect' => route('dashboard')
]);
}public static function validatedFormData($request)
{
try {
// Your logic here
return response()->json(['success' => true]);
} catch (\Exception $e) {
return response()->json([
'message' => 'An error occurred: ' . $e->getMessage()
], 500);
}
}Show/hide fields based on other field values:
RadioElement::name('account_type')
->items(['personal' => 'Personal', 'business' => 'Business']),
TextElement::name('company_name')
->conditions([
['account_type', '==', 'business']
])SelectElement::name('category_id')
->items(Category::pluck('name', 'id')->toArray())
->search(true)
->placeholder('Select a category...')FileElement::name('avatar')
->accept('image/*')
->uploadTempEndpoint(route('temp.upload'))
->removeTempEndpoint(route('temp.remove'))
->auto(true)return Vueform::build()
->steps([
'personal' => 'Personal Information',
'address' => 'Address Details',
'review' => 'Review & Submit'
])
->schema([
// Step 1
GroupElement::name('personal_info')->schema([...]),
// Step 2
GroupElement::name('address_info')->schema([...]),
// Step 3
StaticElement::name('review')->content('<p>Review your information...</p>')
]);ListElement::name('phone_numbers')
->label('Phone Numbers')
->addText('Add Another Phone')
->object([
'type' => SelectElement::name('type')->items(['mobile', 'home', 'work']),
'number' => TextElement::name('number')->rules('required')
])See the full documentation for detailed element options:
- Text Inputs:
TextElement,TextareaElement,EmailElement,PasswordElement - Numbers:
NumberElement,SliderElement - Selections:
SelectElement,RadioElement,CheckboxElement,ToggleElement - Dates:
DateElement,TimeElement,DatetimeElement - Files:
FileElement,ImageElement - Rich Content:
EditorElement,MarkdownElement - Layout:
GroupElement,ListElement,ColumnsElement - Static:
ButtonElement,StaticElement,HtmlElement
For forms that don't change often:
public function buildForm()
{
return Cache::remember('contact-form-schema', 3600, function() {
return Vueform::build()->schema([...]);
});
}Check: Did you add loadAssets() to your layout?
{{ VueFormLaravel\Abstracts\VueFormBuilder::loadAssets() }}Check: Is the CSRF meta tag present?
<meta name="csrf-token" content="{{ csrf_token() }}">Check: Are rules defined on elements?
TextElement::name('email')->rules('required|email')Solution: Clear browser cache and run:
php artisan cache:clear
php artisan config:clearContributions are welcome! Here's how to get started:
- Fork the repository on GitHub
- Clone your fork:
git clone https://github.com/bijoy4067/vueform-laravel.git - Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes with clear commit messages
- Add tests for new functionality
- Submit a pull request with a description of your changes
- Follow PSR-12 coding standards
- Write PHPDoc comments for public methods
- Include unit tests for new features
- Update documentation for new features
This package is open-sourced software licensed under the MIT license.
- Official Documentation: [Coming Soon]
- Laravel Documentation: https://laravel.com/docs
- Vue 3 Guide: https://vuejs.org
- VueForm: https://vueform.com
- Material Design: https://material.io
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Email: vueformlaravel@gmail.com
Built with β€οΈ for the Laravel community
