jeffersongoncalves / laravel-faq
A Laravel package for managing FAQs with translatable questions, answers, and categories
Fund package maintenance!
Requires
- php: ^8.2
- illuminate/contracts: ^12.0|^13.0
- illuminate/database: ^12.0|^13.0
- illuminate/support: ^12.0|^13.0
- spatie/laravel-package-tools: ^1.15
- spatie/laravel-translatable: ^6.11
Requires (Dev)
- larastan/larastan: ^2.9|^3.0
- laravel/pint: ^1.0
- nunomaduro/collision: ^8.0
- orchestra/testbench: ^10.0|^11.0
- pestphp/pest: ^3.0|^4.0
- pestphp/pest-plugin-laravel: ^3.0|^4.0
README
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.
