❤️ We proudly support the community by developing Laravel packages and giving them away for free. If this package saves you time or if you're relying on it professionally, please consider sponsoring the maintenance and development and check out our latest premium package: Inertia Table. Keeping track of issues and pull requests takes time, but we're happy to help!
- Use the latest version of the Laravel Framework and additional packages.
- Use the least amount of additional packages, and avoid solutions that require the installation of additional tools on the server.
- Stay close to first-party Laravel-style conventions and guidelines. Carefully read the framework documentation and navigate its source code and first-party packages for inspiration.
- Everything should work with Inertia SSR and Laravel Octane.
- Use translation strings, don't hard-code strings. This also applies to data like the app name, company name, company address, etc. Things may change over time.
- Prefer storing app-specific settings (like enabling or disabling a feature) in the database rather than configuration files.
- Avoid events/listeners. As always, it depends on the situation. If we're talking about 5+ actions, this might become cumbersome, and you want to use listeners. But my starting point is to keep it simple within the controller and refactor when it becomes more complex.
- Use atomic locks for actions like account creation, order confirmation, etc.
- Actions that involve an unknown amount or database records should always be queued and never performed synchronously. Show a message to the user that the action is queued. Show the user where or how the status can be seen.
- Present the user clear and informative error messages. Never assume the user knows why something fails.
- Write tests for everything. Also, every endpoint should have a Laravel Dusk E2E test, and every feature should have its own test.
- Ensure that all requests using the HTTP Client have been faked.
- Keep controllers minimalistic and use actions similar to Laravel Fortify. For example, an interface would be named
UpdatesUserProfileInformation
, and its implementationUpdateUserProfileInformation
. - Keep an activity log of all non-GET requests.
- Don't limit controller methods to CRUD methods. It's perfectly fine to add an
approve
method, or use an invokableApproveBlogPost
controller.
- Implement CSP and other security-related headers from the start. Don't think of it as an after sight.
- Protect your app against Cross-site scripting (XSS). Not only escape user input at the front-end but use the XSS Protection Middleware package to sanitize request input.
- Prefer uploading files to an external service like S3 instead of allowing file uploads directly to your app server. You may prevent file uploads with the XSS package.
- Create sensible Model Factories and Seeders. After cloning this repo, there should be a single seeder that you can run to interact with all parts of the app.
- If you need to display a set of database records, always use pagination.
- If you need to loop over database records and do some work, always use chunks with the
chunk
orchunkById
method. - Never leak Eloquent Models into the front-end. Always use API Resources and don't use
toArray()
on a Model. Also, never directly use a request to save a model (e.g.Model::create($request->all())
). Always validate and manually specify all fields (e.g.Model::create($request->validated())
). This way, we can unguard the models. - Use the static
query()
method to begin querying an Eloquent Model. - Use Incrementing IDs as the internal primary key. Use UUIDs for consumer-facing endpoints.
- Prefer timestamps over booleans. For example,
published_at
instead ofis_published
. - Always prevent the lazy loading of relationships.
- Keep an eye on the duration of individual database queries. You may add this snippet, which I found in the
handleExceedingCumulativeQueryDuration
PR.
if (!app()->isProduction()) {
DB::listen(function (QueryExecuted $event) {
if ($event->time > 100) {
throw new QueryException(
$event->sql,
$event->bindings,
new Exception("Individual database query exceeded 100ms.")
);
}
});
}
- For all data, write a mechanism to delete it as well. Make sure files and database records are deletable without breaking the application.
- Enforce a morph map to ensure all polymorphs relationships are mapped to an alias:
Relation::requireMorphMap()
. - Be careful with chaining
orWhere*
constraints. When combined with other constraints, you often need to wraporWhere*
method calls.
- Prefer attaching a PDF to a Mailable rather than using more text or data in the mail contents.
- There must be a way for users to resend a Mailable, for example, an order confirmation.
- When you automate notifications, for example, a cronjob that sends invoice payment reminders, always store a timestamp of the moment you've sent it. You may run the cronjob unlimited times without worrying about sending duplicate notifications.
- Always specify a
timeout
on the HTTP Client.
You may use ESLint to find problems that can be automatically fixed. You'll find a sensible default .eslintrc.js
file in this repository.
npm install eslint eslint-plugin-vue --dev
NPM script:
"scripts": {
"eslint": "./node_modules/.bin/eslint resources/js/ --ext .js,.vue --fix"
}
You may use PHP CS Fixer to fix your code to follow standards. You'll find a sensible default .php-cs-fixer.php
file in this repository.
composer require friendsofphp/php-cs-fixer --dev
Composer script:
"scripts": {
"php-cs-fixer": [
"vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --verbose"
],
}
You may use Babel to support code splitting with Inertia.
npm install @babel/plugin-syntax-dynamic-import --dev
Deprecated: For new projects, start using Vite.
Install Polyfill extension to include polyfills by using Babel, core-js, and regenerator-runtime.
npm install laravel-mix-polyfill --dev
Checkout the webpack.mix.js
example file, which includes fixes for some older browsers.
We proudly support the community by developing Laravel packages and giving them away for free. Keeping track of issues and pull requests takes time, but we're happy to help! If this package saves you time or if you're relying on it professionally, please consider supporting the maintenance and development.
Inertia Table
: The Ultimate Table for Inertia.js with built-in Query Builder.Laravel Blade On Demand
: Laravel package to compile Blade templates in memory.Laravel Cross Eloquent Search
: Laravel package to search through multiple Eloquent models.Laravel Eloquent Scope as Select
: Stop duplicating your Eloquent query scopes and constraints in PHP. This package lets you re-use your query scopes and constraints by adding them as a subquery.Laravel MinIO Testing Tools
: This package provides a trait to run your tests against a MinIO S3 server.Laravel Mixins
: A collection of Laravel goodies.Laravel Paddle
: Paddle.com API integration for Laravel with support for webhooks/events.Laravel Verify New Email
: This package adds support for verifying new email addresses: when a user updates its email address, it won't replace the old one until the new one is verified.Laravel XSS Protection Middleware
: Laravel Middleware to protect your app against Cross-site scripting (XSS). It sanitizes request input by utilising the Laravel Security package, and it can sanatize Blade echo statements as well.
The MIT License (MIT). Please see License File for more information.