Laravel Faq
#Laravel FAQ
A Laravel package for managing FAQs (Frequently Asked Questions), with translatable categories, questions, and answers powered by spatie/laravel-translatable.
#Features
- FAQ Categories — Organize FAQs into categories with a name, slug, order, and active flag
- FAQs — Question/answer pairs, optionally attached to a category (a FAQ can exist without one)
- Translatable Content — Category names, questions, and answers are translatable via
spatie/laravel-translatable, with automatic fallback to the app's fallback locale - Ordering & Activation —
ordered()andactive()query scopes on both models - Configurable Table Names — Override the
faq_categories/faqstable names via config - Configurable Locales — Mirrors
app.available_locales(or the app locale) to describe supported translation locales
#Requirements
- PHP 8.2+
- Laravel 12.x or 13.x
#Installation
You can install the package via composer:
composer require jeffersongoncalves/laravel-faq
Publish and run the migrations:
php artisan vendor:publish --tag="faq-migrations" php artisan migrate
Publish the config file (optional):
php artisan vendor:publish --tag="faq-config"
#Configuration
The config file (config/faq.php) covers:
#Table Names
'table_names' => [ 'categories' => 'faq_categories', 'faqs' => 'faqs', ],
#Locales
'locales' => config('app.available_locales') ? array_keys(config('app.available_locales')) : [config('app.locale', 'en')],
Reads from app.available_locales (an array keyed by locale code, e.g. ['en' => 'English', 'pt_BR' => 'Português']) when present, otherwise falls back to the app's default locale. The package also configures spatie/laravel-translatable's fallback behavior on boot, so a missing translation for the current locale falls back to app.fallback_locale (or any available locale if that is also missing).
#Usage
#Categories
use JeffersonGoncalves\Faq\Models\FaqCategory; $category = FaqCategory::create([ 'name' => ['en' => 'Billing', 'pt_BR' => 'Faturamento'], 'slug' => 'billing', 'order' => 1, 'is_active' => true, ]); $category->getTranslation('name', 'pt_BR'); // 'Faturamento' $category->setTranslation('name', 'es', 'Facturación'); $category->save();
#FAQs
use JeffersonGoncalves\Faq\Models\Faq; $faq = Faq::create([ 'faq_category_id' => $category->id, // nullable — FAQs can exist without a category 'question' => ['en' => 'How do I update my payment method?'], 'answer' => ['en' => 'Go to Settings > Billing and click "Update payment method".'], 'order' => 1, 'is_active' => true, ]); $faq->question; // resolved for the current app locale, with fallback $faq->category; // the related FaqCategory, or null
#Scopes
FaqCategory::active()->ordered()->get(); Faq::active()->ordered()->get(); $category->faqs()->active()->ordered()->get();
#Translations
Because both models use Spatie\Translatable\HasTranslations, the full spatie/laravel-translatable API is available:
$faq->getTranslation('question', 'pt_BR'); $faq->setTranslation('question', 'pt_BR', 'Como atualizo minha forma de pagamento?'); $faq->getTranslations('question'); // ['en' => '...', 'pt_BR' => '...'] $faq->translate('question', 'pt_BR');
#Testing
composer test
#Changelog
Please see CHANGELOG for more information on what has changed recently.
#Contributing
Please see CONTRIBUTING for details.
#Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
#Credits
#License
The MIT License (MIT). Please see License File for more information.