Laravel best practices

Related tags

Laravel laravel
Overview

Laravel best practices

Translations:

Nederlands (by Protoqol)

Indonesia (by P0rguy, Doni Ahmad)

한국어 (by cherrypick)

日本語 (by 2bo)

简体中文 (by xiaoyi)

繁體中文 (by woeichern)

ภาษาไทย (by kongvut sangkla)

বাংলা (by Anowar Hossain)

فارسی (by amirhossein baghaie)

Português (by jonaselan)

Українська (by Tenevyk)

Русский

Tiếng Việt (by Chung Nguyễn)

Español (by César Escudero)

Français (by Mikayil S.)

Polski (by Karol Pietruszka)

Türkçe (by Burak)

Deutsch (by Sujal Patel)

Italiana (by Sujal Patel)

Azərbaycanca (by Maharramoff)

العربية (by ahmedsaoud31)

اردو (by RizwanAshraf1)

It's not a Laravel adaptation of SOLID principles, patterns etc. Here you'll find the best practices which are usually ignored in real life Laravel projects.

Contents

Single responsibility principle

Fat models, skinny controllers

Validation

Business logic should be in service class

Don't repeat yourself (DRY)

Prefer to use Eloquent over using Query Builder and raw SQL queries. Prefer collections over arrays

Mass assignment

Do not execute queries in Blade templates and use eager loading (N + 1 problem)

Chunk data for data-heavy tasks

Comment your code, but prefer descriptive method and variable names over comments

Do not put JS and CSS in Blade templates and do not put any HTML in PHP classes

Use config and language files, constants instead of text in the code

Use standard Laravel tools accepted by community

Follow Laravel naming conventions

Use shorter and more readable syntax where possible

Use IoC container or facades instead of new Class

Do not get data from the .env file directly

Store dates in the standard format. Use accessors and mutators to modify date format

Other good practices

Single responsibility principle

A class and a method should have only one responsibility.

Bad:

public function getFullNameAttribute()
{
    if (auth()->user() && auth()->user()->hasRole('client') && auth()->user()->isVerified()) {
        return 'Mr. ' . $this->first_name . ' ' . $this->middle_name . ' ' . $this->last_name;
    } else {
        return $this->first_name[0] . '. ' . $this->last_name;
    }
}

Good:

public function getFullNameAttribute(): bool
{
    return $this->isVerifiedClient() ? $this->getFullNameLong() : $this->getFullNameShort();
}

public function isVerifiedClient(): bool
{
    return auth()->user() && auth()->user()->hasRole('client') && auth()->user()->isVerified();
}

public function getFullNameLong(): string
{
    return 'Mr. ' . $this->first_name . ' ' . $this->middle_name . ' ' . $this->last_name;
}

public function getFullNameShort(): string
{
    return $this->first_name[0] . '. ' . $this->last_name;
}

🔝 Back to contents

Fat models, skinny controllers

Put all DB related logic into Eloquent models.

Bad:

public function index()
{
    $clients = Client::verified()
        ->with(['orders' => function ($q) {
            $q->where('created_at', '>', Carbon::today()->subWeek());
        }])
        ->get();

    return view('index', ['clients' => $clients]);
}

Good:

public function index()
{
    return view('index', ['clients' => $this->client->getWithNewOrders()]);
}

class Client extends Model
{
    public function getWithNewOrders(): Collection
    {
        return $this->verified()
            ->with(['orders' => function ($q) {
                $q->where('created_at', '>', Carbon::today()->subWeek());
            }])
            ->get();
    }
}

🔝 Back to contents

Validation

Move validation from controllers to Request classes.

Bad:

public function store(Request $request)
{
    $request->validate([
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
        'publish_at' => 'nullable|date',
    ]);

    ....
}

Good:

public function store(PostRequest $request)
{    
    ....
}

class PostRequest extends Request
{
    public function rules(): array
    {
        return [
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
            'publish_at' => 'nullable|date',
        ];
    }
}

🔝 Back to contents

Business logic should be in service class

A controller must have only one responsibility, so move business logic from controllers to service classes.

Bad:

public function store(Request $request)
{
    if ($request->hasFile('image')) {
        $request->file('image')->move(public_path('images') . 'temp');
    }
    
    ....
}

Good:

public function store(Request $request)
{
    $this->articleService->handleUploadedImage($request->file('image'));

    ....
}

class ArticleService
{
    public function handleUploadedImage($image): void
    {
        if (!is_null($image)) {
            $image->move(public_path('images') . 'temp');
        }
    }
}

🔝 Back to contents

Don't repeat yourself (DRY)

Reuse code when you can. SRP is helping you to avoid duplication. Also, reuse Blade templates, use Eloquent scopes etc.

Bad:

public function getActive()
{
    return $this->where('verified', 1)->whereNotNull('deleted_at')->get();
}

public function getArticles()
{
    return $this->whereHas('user', function ($q) {
            $q->where('verified', 1)->whereNotNull('deleted_at');
        })->get();
}

Good:

public function scopeActive($q)
{
    return $q->where('verified', true)->whereNotNull('deleted_at');
}

public function getActive(): Collection
{
    return $this->active()->get();
}

public function getArticles(): Collection
{
    return $this->whereHas('user', function ($q) {
            $q->active();
        })->get();
}

🔝 Back to contents

Prefer to use Eloquent over using Query Builder and raw SQL queries. Prefer collections over arrays

Eloquent allows you to write readable and maintainable code. Also, Eloquent has great built-in tools like soft deletes, events, scopes etc.

Bad:

SELECT *
FROM `articles`
WHERE EXISTS (SELECT *
              FROM `users`
              WHERE `articles`.`user_id` = `users`.`id`
              AND EXISTS (SELECT *
                          FROM `profiles`
                          WHERE `profiles`.`user_id` = `users`.`id`) 
              AND `users`.`deleted_at` IS NULL)
AND `verified` = '1'
AND `active` = '1'
ORDER BY `created_at` DESC

Good:

Article::has('user.profile')->verified()->latest()->get();

🔝 Back to contents

Mass assignment

Bad:

$article = new Article;
$article->title = $request->title;
$article->content = $request->content;
$article->verified = $request->verified;
// Add category to article
$article->category_id = $category->id;
$article->save();

Good:

$category->article()->create($request->validated());

🔝 Back to contents

Do not execute queries in Blade templates and use eager loading (N + 1 problem)

Bad (for 100 users, 101 DB queries will be executed):

@foreach (User::all() as $user)
    {{ $user->profile->name }}
@endforeach

Good (for 100 users, 2 DB queries will be executed):

$users = User::with('profile')->get();

...

@foreach ($users as $user)
    {{ $user->profile->name }}
@endforeach

🔝 Back to contents

Chunk data for data-heavy tasks

Bad ():

$users = $this->get();

foreach ($users as $user) {
    ...
}

Good:

$this->chunk(500, function ($users) {
    foreach ($users as $user) {
        ...
    }
});

🔝 Back to contents

Prefer descriptive method and variable names over comments

Bad:

// Determine if there are any joins
if (count((array) $builder->getQuery()->joins) > 0)

Good:

if ($this->hasJoins())

🔝 Back to contents

Do not put JS and CSS in Blade templates and do not put any HTML in PHP classes

Bad:

let article = `{{ json_encode($article) }}`;

Better:

<input id="article" type="hidden" value='@json($article)'>

Or

<button class="js-fav-article" data-article='@json($article)'>{{ $article->name }}<button>

In a Javascript file:

let article = $('#article').val();

The best way is to use specialized PHP to JS package to transfer the data.

🔝 Back to contents

Use config and language files, constants instead of text in the code

Bad:

public function isNormal(): bool
{
    return $article->type === 'normal';
}

return back()->with('message', 'Your article has been added!');

Good:

public function isNormal()
{
    return $article->type === Article::TYPE_NORMAL;
}

return back()->with('message', __('app.article_added'));

🔝 Back to contents

Use standard Laravel tools accepted by community

Prefer to use built-in Laravel functionality and community packages instead of using 3rd party packages and tools. Any developer who will work with your app in the future will need to learn new tools. Also, chances to get help from the Laravel community are significantly lower when you're using a 3rd party package or tool. Do not make your client pay for that.

Task Standard tools 3rd party tools
Authorization Policies Entrust, Sentinel and other packages
Compiling assets Laravel Mix Grunt, Gulp, 3rd party packages
Development Environment Laravel Sail, Homestead Docker
Deployment Laravel Forge Deployer and other solutions
Unit testing PHPUnit, Mockery Phpspec
Browser testing Laravel Dusk Codeception
DB Eloquent SQL, Doctrine
Templates Blade Twig
Working with data Laravel collections Arrays
Form validation Request classes 3rd party packages, validation in controller
Authentication Built-in 3rd party packages, your own solution
API authentication Laravel Passport, Laravel Sanctum 3rd party JWT and OAuth packages
Creating API Built-in Dingo API and similar packages
Working with DB structure Migrations Working with DB structure directly
Localization Built-in 3rd party packages
Realtime user interfaces Laravel Echo, Pusher 3rd party packages and working with WebSockets directly
Generating testing data Seeder classes, Model Factories, Faker Creating testing data manually
Task scheduling Laravel Task Scheduler Scripts and 3rd party packages
DB MySQL, PostgreSQL, SQLite, SQL Server MongoDB

🔝 Back to contents

Follow Laravel naming conventions

Follow PSR standards.

Also, follow naming conventions accepted by Laravel community:

What How Good Bad
Controller singular ArticleController ArticlesController
Route plural articles/1 article/1
Named route snake_case with dot notation users.show_active users.show-active, show-active-users
Model singular User Users
hasOne or belongsTo relationship singular articleComment articleComments, article_comment
All other relationships plural articleComments articleComment, article_comments
Table plural article_comments article_comment, articleComments
Pivot table singular model names in alphabetical order article_user user_article, articles_users
Table column snake_case without model name meta_title MetaTitle; article_meta_title
Model property snake_case $model->created_at $model->createdAt
Foreign key singular model name with _id suffix article_id ArticleId, id_article, articles_id
Primary key - id custom_id
Migration - 2017_01_01_000000_create_articles_table 2017_01_01_000000_articles
Method camelCase getAll get_all
Method in resource controller table store saveArticle
Method in test class camelCase testGuestCannotSeeArticle test_guest_cannot_see_article
Variable camelCase $articlesWithAuthor $articles_with_author
Collection descriptive, plural $activeUsers = User::active()->get() $active, $data
Object descriptive, singular $activeUser = User::active()->first() $users, $obj
Config and language files index snake_case articles_enabled ArticlesEnabled; articles-enabled
View kebab-case show-filtered.blade.php showFiltered.blade.php, show_filtered.blade.php
Config snake_case google_calendar.php googleCalendar.php, google-calendar.php
Contract (interface) adjective or noun AuthenticationInterface Authenticatable, IAuthentication
Trait adjective Notifiable NotificationTrait

🔝 Back to contents

Use shorter and more readable syntax where possible

Bad:

$request->session()->get('cart');
$request->input('name');

Good:

session('cart');
$request->name;

More examples:

Common syntax Shorter and more readable syntax
Session::get('cart') session('cart')
$request->session()->get('cart') session('cart')
Session::put('cart', $data) session(['cart' => $data])
$request->input('name'), Request::get('name') $request->name, request('name')
return Redirect::back() return back()
is_null($object->relation) ? null : $object->relation->id optional($object->relation)->id (in PHP 8: $object->relation?->id)
return view('index')->with('title', $title)->with('client', $client) return view('index', compact('title', 'client'))
$request->has('value') ? $request->value : 'default'; $request->get('value', 'default')
Carbon::now(), Carbon::today() now(), today()
App::make('Class') app('Class')
->where('column', '=', 1) ->where('column', 1)
->orderBy('created_at', 'desc') ->latest()
->orderBy('age', 'desc') ->latest('age')
->orderBy('created_at', 'asc') ->oldest()
->select('id', 'name')->get() ->get(['id', 'name'])
->first()->name ->value('name')

🔝 Back to contents

Use IoC container or facades instead of new Class

new Class syntax creates tight coupling between classes and complicates testing. Use IoC container or facades instead.

Bad:

$user = new User;
$user->create($request->validated());

Good:

public function __construct(User $user)
{
    $this->user = $user;
}

....

$this->user->create($request->validated());

🔝 Back to contents

Do not get data from the .env file directly

Pass the data to config files instead and then use the config() helper function to use the data in an application.

Bad:

$apiKey = env('API_KEY');

Good:

// config/api.php
'key' => env('API_KEY'),

// Use the data
$apiKey = config('api.key');

🔝 Back to contents

Store dates in the standard format. Use accessors and mutators to modify date format

Bad:

{{ Carbon::createFromFormat('Y-d-m H-i', $object->ordered_at)->toDateString() }}
{{ Carbon::createFromFormat('Y-d-m H-i', $object->ordered_at)->format('m-d') }}

Good:

// Model
protected $dates = ['ordered_at', 'created_at', 'updated_at'];
public function getSomeDateAttribute($date)
{
    return $date->format('m-d');
}

// View
{{ $object->ordered_at->toDateString() }}
{{ $object->ordered_at->some_date }}

🔝 Back to contents

Other good practices

Avoid using patterns and tools that are alien to Laravel and similar frameworks (i.e. RoR, Django). If you like Symfony (or Spring) approach for building apps, it's a good idea to use these frameworks instead.

Never put any logic in routes files.

Minimize usage of vanilla PHP in Blade templates.

Use in-memory DB for testing.

Do not override standard framework features to avoid problems related to updating the framework version and many other issues.

Use modern PHP syntax where possible, but don't forget about readability.

Avoid using View Composers and similar tools unless you really know what you're doing. In most cases, there is a better way to solve the problem.

🔝 Back to contents

Comments
  • Ukrainian translation

    Ukrainian translation

    Hey there, Alexey!

    I want to translate these wonderful practices in Ukrainian language. Which font and its size I need to use for the image of Laravel? That info would be enough for me to start the translation.

    Thank you!

    opened by Tenevyk 16
  • Store dates in the standard format. Use accessors and mutators to modify date format

    Store dates in the standard format. Use accessors and mutators to modify date format

    I agree with this description and this rule, but the example is unclear and confusing.

    Basically we should be illustrating that you should be passing Carbon objects (as per the rest of the guide), and not creating new objects with unique formatting, etc.

    opened by JohnnyWalkerDesign 11
  • Traits and interfaces indistinguishable by name

    Traits and interfaces indistinguishable by name

    Can't we make it more clear by name if the "class" is a trait or an interfaces as they both are adjectives now. I understand the reasoning but we also need a solution (I think). We might consider recommending creating an interface for every trait.

    opened by thomasmoors 11
  • Poll: Can we change the rule for Interfaces/Contracts to be suffixed with

    Poll: Can we change the rule for Interfaces/Contracts to be suffixed with "Interface"?

    1. This way it's compatible with PSR naming conventions.
    2. You can differentiate Interfaces from Traits by class name, otherwise they might be the same.

    This poll was created based on a suggestion by the author: https://github.com/alexeymezenin/laravel-best-practices/issues/44#issuecomment-651786852 Please upvote with a thumbs up and downvote with a thumbs down.

    image

    opened by thomasmoors 7
  • What are your thought on this?

    What are your thought on this?

    Business logic should be in service class

    • I don't think it's best practice to pass a Laravel's Request object to the Service Layer.
    • Why?
      • Because, it's HTTP specific data object. If your Service Object depends on delivery mechanism, you can't reuse the service object in Console Command or Queue Job.
      • Furthermore the Request object is an object from the framework, and HEAVY. laravel_request
      • I know you may argue that not only the Request object is already on the memory and passing it is merely a memory reference in the runtime, also additional unnecessary memory usage due to Dto object. But in personal I'll choose maintenability and readibility.
    • Then what?
      • I'd like you to use a Boundary Object, namely Dto.
      • Make the Laravel Request object new up a Dto. And make the Service object use Dto.
    Class CreateUserRequest
    {
        public function rules()
        {
            return [
                // ...
            ];
        }
    
        public function getUserDto()
        {
            return new UserDto(
                $this->input('user_name', null),
                // ...
            );
        }
    }
    
    Class UserController
    {
        public function createUser(CreateUserRequest $request, UserCreator $creator)
        {
            $dto = $request->getUserDto();
            DB::transaction(function () use ($creator, $dto) {
                $user = $creator->createUser($dto);
                $user->save();
            });
    
            // ...
        }
    }
    
    Class CreateUserCommand
    {
        public function handle(UserCreator $creator)
        {
            $dto = new UserDto(
                $this->argument('user_name'),
                // ...
            );
            DB::transaction(function () use ($creator, $dto) {
                $user = $creator->createUser($dto);
                $user->save();
            });
    
            // ...
        }
    }
    

    Don't repeat yourself (DRY)

    • I don't like whereHas() example.
    • Because under the the hood, the query builder translate whereHas() to exists subquery.
    • And it leads you to a huage performance degradation, especially when you have a large volume of records.

    Mass assignment

    • I don't think mass assignment is a good practice, when your service is NOT TRIVIAL.
    • As the document mentioned earlier, I would recommend to use a Sservice Object and mutate each property one by one.
    • For example:
    class UserCreator
    {
        public function createUser(UserDto $dto)
        {
            $user = new User();
            $user->name = $dto->getUserName();
            // You can hook into Model Validation(==Business Policy) logic here
            // With mass assignment, you will loose the model validation chance
            // ...
            return $user;
        }
    }
    
    class UserModifier
    {
        public function modifyUser(User $user, UserDto $dto)
        {
            $name = $dto->getUserName();
            if ($name !== null) {
                // Again you can do the model validation here
                $user->name = $name;
            }
            // ...
            // Donot return the $user, because it was passed by reference.
        }
    }
    

    Use shorter and more readable syntax where possible

    • Maybe it's OK to use Laravel's global helper functions in a Controller but not in a Domain Logic.
    • I think the document is leading people being tightly coupled to the framework.
    opened by appkr 7
  • URI naming convertion?

    URI naming convertion?

    E.g.: $router->get('/users/forgot_password', 'UserController@forgotPassword'); or $router->get('/users/forgot-password', 'UserController@forgotPassword'); or $router->get('/users/forgotPassword', 'UserController@forgotPassword');

    there's no clue in Resource Controllers doc, but I guess forgot-password seems to be the way to go.

    opened by sweatyc 6
  • Fix blade file name convention

    Fix blade file name convention

    I think it's better to follow the framework naming convention. In this package they are using kebab-case instead of snake_case for blade files. https://github.com/illuminate/pagination/tree/master/resources/views

    opened by Daniyal-Javani 5
  • avoid using request()->all()

    avoid using request()->all()

    request()->all() can be dangerous because when used may cause a security vulnerability.

    for example:

    # database
    users:
       - id
      - username
      - password
      - email
      - superuser (bool)
    
    # controller
    public function store(Request $request) {
      User::create($request->all());
      return back()->with('alert', 'user created!');
    }
    

    if am i a hacker-boy and send a payload with input[name=superuser]=1 magically I will become a superadmin.


    bad:

    public function store(Request $request) {
      User::create($request->all());
      return back()->with('alert', 'user created!');
    }
    

    good:

    public function store(Request $request) {
      User::create($request->only('username', 'password', 'email'));
      return back()->with('alert', 'user created!');
    }
    
    opened by gpedro 5
  • Naming convention for Request classes

    Naming convention for Request classes

    Is there a particular convention that should be followed for Request classes? For example, if I need different Request class for store and update, instead of PostRequest, what should I name my Request classes?

    NewPostRequest and UpdatePostRequest? PostNewRequestand PostUpdateRequest? StorePostRequest and UpdatePostRequest? PostStoreRequestand PostUpdateRequest?

    Something else entirely?

    opened by g011um 5
  • Is there a way to print this?

    Is there a way to print this?

    First, thank you to those who have made this possible, as a new developer I find this extremely helpful!

    I was wondering if there's a way to print this out so I can have it available offline for when I'm not at my desk.

    opened by FoxRocks76 3
  • How can PHP framework propose a table naming convention in a database (SQL, NoSQL)?

    How can PHP framework propose a table naming convention in a database (SQL, NoSQL)?

    Does it make sense to recommend database naming in context of PHP framework? May be this is confusing for less experienced developers? And implies violation of best practices, if database is already designed using singular naming style?

    Are these practices of database naming possible, if database is already designed using singular naming style? https://github.com/alexeymezenin/laravel-best-practices#follow-laravel-naming-conventions

    Does it means that singular naming at database is not good for Laravel?

    opened by vanyabrovary 3
  • Recommended route name conflict?

    Recommended route name conflict?

    The recommended route naming convention is snake_case with dot notation: https://github.com/alexeymezenin/laravel-best-practices#follow-laravel-naming-conventions

    However, Laravel itself follows the casing of the resource when generating multi-word route resource names, and kebab-case in its own support packages (e.g., Sanctum):

    Route::resource('my-complex-resource', MyComplexResourceController::class);
    Route::resource('my_complex_resource', MyComplexResourceController::class);
    Route::resource('myComplexResource', MyComplexResourceController::class);
    
    GET|HEAD        my-complex-resource ............................. my-complex-resource.index › MyComplexResourceController@index
    POST            my-complex-resource ............................. my-complex-resource.store › MyComplexResourceController@store
    GET|HEAD        my-complex-resource/create .................... my-complex-resource.create › MyComplexResourceController@create
    GET|HEAD        my-complex-resource/{my_complex_resource} ......... my-complex-resource.show › MyComplexResourceController@show
    PUT|PATCH       my-complex-resource/{my_complex_resource} ..... my-complex-resource.update › MyComplexResourceController@update
    DELETE          my-complex-resource/{my_complex_resource} ... my-complex-resource.destroy › MyComplexResourceController@destroy
    GET|HEAD        my-complex-resource/{my_complex_resource}/edit .... my-complex-resource.edit › MyComplexResourceController@edit
    GET|HEAD        myComplexResource ................................. myComplexResource.index › MyComplexResourceController@index
    POST            myComplexResource ................................. myComplexResource.store › MyComplexResourceController@store
    GET|HEAD        myComplexResource/create ........................ myComplexResource.create › MyComplexResourceController@create
    GET|HEAD        myComplexResource/{myComplexResource} ............... myComplexResource.show › MyComplexResourceController@show
    PUT|PATCH       myComplexResource/{myComplexResource} ........... myComplexResource.update › MyComplexResourceController@update
    DELETE          myComplexResource/{myComplexResource} ......... myComplexResource.destroy › MyComplexResourceController@destroy
    GET|HEAD        myComplexResource/{myComplexResource}/edit .......... myComplexResource.edit › MyComplexResourceController@edit
    GET|HEAD        my_complex_resource ............................. my_complex_resource.index › MyComplexResourceController@index
    POST            my_complex_resource ............................. my_complex_resource.store › MyComplexResourceController@store
    GET|HEAD        my_complex_resource/create .................... my_complex_resource.create › MyComplexResourceController@create
    GET|HEAD        my_complex_resource/{my_complex_resource} ......... my_complex_resource.show › MyComplexResourceController@show
    PUT|PATCH       my_complex_resource/{my_complex_resource} ..... my_complex_resource.update › MyComplexResourceController@update
    DELETE          my_complex_resource/{my_complex_resource} ... my_complex_resource.destroy › MyComplexResourceController@destroy
    GET|HEAD        my_complex_resource/{my_complex_resource}/edit .... my_complex_resource.edit › MyComplexResourceController@edit
    GET|HEAD        sanctum/csrf-cookie ......................... sanctum.csrf-cookie › Laravel\Sanctum › CsrfCookieController@show
    

    And since kebab-case is the accepted URI convention shouldn't it also be the named route convention?

    opened by benjivm 0
  • Make use of helpers function and remember to make add_debug true on production

    Make use of helpers function and remember to make add_debug true on production

    Some more contribution. #Just a contribution to the document, ensuring the app_debug is always set to true after deployment. #Using the helper function available on the Illuminate/Support instead of making a new custom helper function

    opened by Masei25 2
  • Validation FormRequest

    Validation FormRequest

    Hi! The Validation example just uses Request as class to inherit. However laravel by default creates a FormRequest instead. What I need is a request to validate my json, but I currently do not know which one is the right one. Maybe you could add some more hints to this example?

    opened by NicoHood 1
Owner
null
The best squirrel tracker. Ever. (A demo app for LaravelSF meetups)

LaraSqrrl Identify and track squirrels via text, now using AWS Rekognition! Created for the November 10th, 2015; February 9th, 2016; May 10th, 2016; a

Paul Foryt 3 Mar 29, 2022
List of 77 languages for Laravel Framework 4, 5, 6, 7 and 8, Laravel Jetstream , Laravel Fortify, Laravel Breeze, Laravel Cashier, Laravel Nova and Laravel Spark.

Laravel Lang In this repository, you can find the lang files for the Laravel Framework 4/5/6/7/8, Laravel Jetstream , Laravel Fortify, Laravel Cashier

Laravel Lang 6.9k Jan 2, 2023
⚡ Laravel Charts — Build charts using laravel. The laravel adapter for Chartisan.

What is laravel charts? Charts is a Laravel library used to create Charts using Chartisan. Chartisan does already have a PHP adapter. However, this li

Erik C. Forés 31 Dec 18, 2022
Laravel Kickstart is a Laravel starter configuration that helps you build Laravel websites faster.

Laravel Kickstart What is Laravel Kickstart? Laravel Kickstart is a Laravel starter configuration that helps you build Laravel websites faster. It com

Sam Rapaport 46 Oct 1, 2022
Laravel User Activity Log - a package for Laravel 8.x that provides easy to use features to log the activities of the users of your Laravel app

Laravel User Activity Log - a package for Laravel 8.x that provides easy to use features to log the activities of the users of your Laravel app

null 9 Dec 14, 2022
Laravel Segment is an opinionated, approach to integrating Segment into your Laravel application.

Laravel Segment Laravel Segment is an opinionated, approach to integrating Segment into your Laravel application. Installation You can install the pac

Octohook 13 May 16, 2022
Laravel Sanctum support for Laravel Lighthouse

Lighthouse Sanctum Add Laravel Sanctum support to Lighthouse Requirements Installation Usage Login Logout Register Email Verification Forgot Password

Daniël de Wit 43 Dec 21, 2022
Bring Laravel 8's cursor pagination to Laravel 6, 7

Laravel Cursor Paginate for laravel 6,7 Installation You can install the package via composer: composer require vanthao03596/laravel-cursor-paginate U

Pham Thao 9 Nov 10, 2022
A package that uses blade templates to control how markdown is converted to HTML inside Laravel, as well as providing support for markdown files to Laravel views.

Install Install via composer. $ composer require olliecodes/laravel-etched-blade Once installed you'll want to publish the config. $ php artisan vendo

Ollie Codes 19 Jul 5, 2021
A light weight laravel package that facilitates dealing with arabic concepts using a set of classes and methods to make laravel speaks arabic

A light weight laravel package that facilitates dealing with arabic concepts using a set of classes and methods to make laravel speaks arabic! concepts like , Hijri Dates & Arabic strings and so on ..

Adnane Kadri 49 Jun 22, 2022
Jetstrap is a lightweight laravel 8 package that focuses on the VIEW side of Jetstream / Breeze package installed in your Laravel application

A Laravel 8 package to easily switch TailwindCSS resources generated by Laravel Jetstream and Breeze to Bootstrap 4.

null 686 Dec 28, 2022
Laravel Jetstream is a beautifully designed application scaffolding for Laravel.

Laravel Jetstream is a beautifully designed application scaffolding for Laravel. Jetstream provides the perfect starting point for your next Laravel application and includes login, registration, email verification, two-factor authentication, session management, API support via Laravel Sanctum, and optional team management.

The Laravel Framework 3.5k Jan 8, 2023
Laravel Larex lets you translate your whole Laravel application from a single CSV file.

Laravel Larex Translate Laravel Apps from a CSV File Laravel Larex lets you translate your whole Laravel application from a single CSV file. You can i

Luca Patera 68 Dec 12, 2022
A Laravel package that adds a simple image functionality to any Laravel model

Laraimage A Laravel package that adds a simple image functionality to any Laravel model Introduction Laraimage served four use cases when using images

Hussein Feras 52 Jul 17, 2022
A Laravel extension for using a laravel application on a multi domain setting

Laravel Multi Domain An extension for using Laravel in a multi domain setting Description This package allows a single Laravel installation to work wi

null 658 Jan 6, 2023
Example of using abrouter/abrouter-laravel-bridge in Laravel

ABRouter Laravel Example It's a example of using (ABRouter Laravel Client)[https://github.com/abrouter/abrouter-laravel-bridge] Set up locally First o

ABRouter 1 Oct 14, 2021
Laravel router extension to easily use Laravel's paginator without the query string

?? THIS PACKAGE HAS BEEN ABANDONED ?? We don't use this package anymore in our own projects and cannot justify the time needed to maintain it anymore.

Spatie 307 Sep 23, 2022
Laravel application project as Sheina Online Store backend to be built with Laravel and VueJS

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

Boas Aditya Christian 1 Jan 11, 2022
Postgis extensions for laravel. Aims to make it easy to work with geometries from laravel models.

Laravel Wrapper for PostgreSQL's Geo-Extension Postgis Features Work with geometry classes instead of arrays. $model->myPoint = new Point(1,2); //lat

Max 340 Jan 6, 2023