Home

3 minute read

Laravel Folio

Tony Lea

Laravel Folio

Laravel Folio is a page-based routing system introduced to Laravel at LaraconUS 2023. With Folio you can map a route to a specific file or folder, similar to the file-based routing systems found in frameworks like NextJS or NuxtJS.

Laravel Folio Screenshot

How it works

After you install Folio into your application you can create a new page with the following artisan command:

php artisan make:folio index

This will place a new file inside of a new pages directory located at resources/views/pages/index.blade.php

pages.png

Now, when visiting your application in the browser it will load this template as the homepage.

Wildcard Pages

We can also create dynamic pages using wildcards. As an example, say that we wanted to visit a route that looks like /users/1. We could create a file named [id].blade.php inside of a users folder, like so:

├── resources
│   ├── views
│   │   ├── pages
│   │   │   ├── users
│   │   │   │   ├── [id].blade.php

Inside the file we will now have access to $id which can be used to lookup the user.

Taking this a step further, we can take advantage of Route Model Binding and rename our file to look like [User:id].blade.php

├── resources
│   ├── views
│   │   ├── pages
│   │   │   ├── users
│   │   │   │   ├── [User:id].blade.php

Inside this file we will now have access to the $user object.

If instead, we wanted to specify the username in the URL parameter, we could easily rename the file to [User:username].blade.php. Then, visiting our application URL at /users/taylorotwell will give us access to the user object who's username is taylorotwell. Here's an example:

<x-layout>
    <h1>Hello {{ $user->name }}</h1>
</x-layout>

Wildcard Directories

We can also create Wildcard Directories. To illustrate this example, say that we wanted to create an info page for every user. We could create a dynamic URL that looks like: /users/taylorotwell/info, by creating the following folder structure:

├── resources
│   ├── views
│   │   ├── pages
│   │   │   ├── users
│   │   │   │   ├── [User:username]
│   │   │   │   │   ├── info.blade.php

We can also create dynamic directories with dynamic pages, like so:

├── resources
│   ├── views
│   │   ├── pages
│   │   │   ├── users
│   │   │   │   ├── [User]
│   │   │   │   │   ├── posts
│   │   │   │   │   │   ├── [Post:slug].blade.php

This will allow us to access a route in our application that looks like: /users/1/posts/folio-is-awesome. When this route is accessed Folio will try and find a post slug of folio-is-awesome that belongs to user id of 1.

Folio Middleware

You can also take advantage of Middleware with Page-based routing. Using the posts example from the previous section we can accomplish this by adding a new Policy inside of the app/Policies directory, like so:

<?php

namespace App\Policies;

use App\Models\Post;
use App\Models\User;

class PostPolicy
{
    public function view(?User $user, Post $post){
    {
        return false; // return the logic that allows or disallows access
    }
}

Then, inside the view we can add the following code:

<?php

use function Laravel\Folio\{middleware};

middleware(['can:view,post']);

?>
<x-layout>
    <h1>{{ $post->title }}</h1>
    <article>{!! $post->body !!}</article>
</x-layout>

If the user does not have access they will see a 403 Forbidden code; otherwise, they'll be able to view the post 👍

Multi-Segment Pages

You can also create a file that will return all the segments in the URL to the page. For instance, if we have a folder structure that looks like this:

├── resources
│   ├── views
│   │   ├── pages
│   │   │   ├── multi
│   │   │   │   ├── [...ids].blade.php

It will capture the URL located at /multi/1/2/3, returning an array of $id's to the page.

Conclusion

Using Laravel Folio we can create routes in our application by adding files or folders inside of the pages view directory. You may also choose to mix Page-based routes and traditional routes within your application.

You can learn more about Laravel Folio by visiting the Github Repo at https://github.com/laravel/folio. You may also be interested in pairing Laravel Folio with Volt (single-file livewire components), this will give you the power of Livewire inside of your pages.