DEV Community

Cover image for Laravext for Laravel
Arthur Ydalgo
Arthur Ydalgo

Posted on • Edited on

Laravext for Laravel

An Inertia-styled monolith for Laravel with Next.js' file-based routing system and file conventions for Vue and React 🛠️

🏳️ First things first: I'm just sharing something I built by taking what I like the most about Inertia and Next.js and that I thought it could be useful to other people who wanted alternatives to current options. If you don't like it, that's totally ok, but there's no need to offend me in the comments (sorry to post this in the beginning, but I really wanted to avoid toxicity). I'm 100% ok with critiscisms and feedbacks about the tool itself, but please be kind. #peace 🏳️

The documentation can be found at laravext.dev. An introduction video can be found at https://youtu.be/GB0ucJ5-AkA. Also feel free to join the Discord channel at https://dsc.gg/laravext

What is it Laravext?

Laravext is a set of tools aimed to assist the development of Laravel applications with React or Vue. It's name is (just in case you didn't get it) a mix of Laravel and Next.js, although not affiliated or endorsed by any of them. I tried to fit in something that also sounded like "Vue" or "Inertia.js" in the name, but "Laravext" sounded the better, of all the options I thought of. Not that creative, I know. Sue me (just kidding, don't).

You may think of it as a Next.js' file based router inside your Laravel project. There're some methods that slightly remember Inertia.js as well. It offers 3 ways to dinamically create server-side rendered pages based on your needs so your application is SEO friendly, one of them in the Inertia.js style, and two of them in the Blade style.

rick-and-morty-meme

Credits: Rick and Morty - Adult Swim

Well, yes... Moving on.

Why does it exist?

First things first: I don't claim that this is supposed to replace or be better than Next.js/Inertia.js, as each project may have different kind of needs and it's team might have it's preference, and maybe just using blade files with Laravel Folio to automagically create routes from them could be enough for you, or maybe you'll better of with the TALL stack, or perhaps Nuxt.js. In the end, it's your choice.

I wanted to get what I (personally) considered the best parts of Inertia.js and Next.js, and put them together. This was going to be inside a project of mine, but then I realized I could actually try to make a package for other people (and myself) to use, and I would try to learn something along the way about how to build composer and npm packages.

Additionally, you might be asking yourself:

"Why don't you use Next.js?", or even "Why don't you use Inertia.js?"

next-js-fork-meme

Before somebody light up their torches or grab their forks: the following points are my opinions only, based on my personal (in)experiences and troubles. You may disagree with them, and that's fine. Feel free to skip this section.

Inertia.js doesn't have an out-of-the-box file-based routing system like the one Next.js offers. (To the best of my knowledge, at the time of writting). If you want to make it SEO friendly you need to have some kind of access to higher privilages so you can keep a php artisan inertia:start-ssr artisan command running through supervisor or something similar (and so does Laravext, by there's also another approach that you can easily use, if needed. Check the "Server Side Rendering" section of the docs for more informations), which may not be available in a shared environment (which, although less common, is still a thing). Laravext offers, along with the Inertia.js style, two other ways to create server-side rendered pages based on you SEO needs.

Next.js offers server-side rendering of React components, and a great routing system, but I (personally) don't like their caching strategy, and for my use cases there was the need to slap a "use client" for a lot of your pages. I felt a really degraded developer experience while using it, so for me it'd make sense to have a way of being 'use client' by default, and 'use server' when needed. I have other points about it, but I feel that the "Why I Won't Use Next.js" article from Kent C. Dodds summarizes most of what I mean way better than I could. It's a good reading if you're interested.

But, once again, I don't want to trash talk Next.js, or Inertia or any other tool. You should use whatever makes you more productive and pays your bills, and in the end, quoting Kent:

"Whatever you use is probably fine.

Your tool choice matters much less than your skill at using the tool to accomplish your desired outcome (a great user experience)."

Who is it for?

My take is that you might be interested in using Laravext if you fall into one or more of the following categories:

  • you want to have a file-based routing system like Next.js (because you don't want to use react/vue router, or declare them all in your web.php file)
  • you don't want to set up a separate project for your frontend (like Next.js or Nuxt.js)
  • you want some kind of flexibility to sometimes have a partially server-side rendered page for SEO purposes (and don't want to use Inertia.js)
  • you don't like the way Next.js handles their caching strategy
  • you don't want to slap a "use client" in nearly every component you have in your app because it becomes cubersome

Who is it NOT for?

I'll try to be as less biased as possible, but you might not be interested in using Laravext if you fall into one or more of the following categories:

  • you have a simple static page that Next.js (or anything else) could handle just fine
  • you don't like the idea of having a file-based routing system (or don't want to have to follow the page conventions)
  • you don't want to risk using a new package that may not be as stable as you'd like, or runs the risk of being abandoned
  • you want to keep your frontend and backend in separate projects
  • you didn't like it (to each their own)

Remember, this is just my opinion, and you should use whatever suits your needs the best, and there're plenty of tools available for you to use, such as the aforementioned Next.js, Inertia.js, Nuxt.js, TALL stack, Blade Components with Folio, Livewire, etc.

What does it do?

As mentioned before, Laravext takes a lot of inspiration in how Next.js do things.

Laravext offers a way to automagically create routes based on the file structure of the resources/js/nexus (this location is customizable) directory, much like Next.js.

Using the following structure (the example uses .jsx files, but you may also use it with .vue files):

# In a Laravel project
+ resources/js/nexus

  - page.jsx # your-domain.com/

  + catalog
    - page.jsx # /catalog
    + {slug}
      - page.jsx # /catalog/{slug}

  + cart
    - page.jsx # /cart
    + checkout
      - middleware.jsx
      - page.jsx # /cart/checkout

  + (guest)
    - middleware.jsx
    - layout.jsx
    + login
      - page.jsx # /login
    + register
      - page.jsx # /register

  + (auth)
    - middleware.jsx
    + (author)
      - layout.jsx
      - middleware.jsx
      + books
        - page.jsx # /books
        + create
          - page.jsx # /books/create
        + {book}
          - page.jsx # /books/{book}
          + edit
            - page.jsx # /books/{book}/edit
      + orders
        - page.jsx # /orders
        + {order}
          - page.jsx # /orders/{order}

    + (reader)
      - layout.jsx
      - middleware.jsx
      + library
        - page.jsx # /library
        + {slug}
          - page.jsx # /library/{slug}
    ...
    # The rest of your pages
Enter fullscreen mode Exit fullscreen mode

and inserting the following inside the routes/web.php:

Route::laravext();
Enter fullscreen mode Exit fullscreen mode

automagically registers the routes of your application (the resulting URIs are displayed next to each page.jsx as example). Next.js' file conventions can also be applied, such as middlewares, layouts, error, etc. You can have granular control in a Inertia-styled approach about what happens before a route is rendered, if needed (check the Tools/Nexus Response documentation section for more details).

A blade view (either the default one set in the config or specified one when the Route::laravext() is called and a root_view parameter is sent) is then rendered by the blade template engine. This view must contain what is called a @nexus blade directive (which you can read about at Tools/Blade Directives), where the react component will be rendered. There're other ways render a nexus that are covered in the docs, more specifically in the Tools/Routing and Tools/Nexus Response.

Additionally, in case you have components that are common to multiple pages, such as navbars, you can use the @strand('Path/To/NavBar') directive alongside a @nexus, which will use the name as a path to find a react component inside the resources/js/strands (which is customizable). The previous example would load a NavBar.jsx from the resources/js/strands/Path/To directory.

Here's an example to how you could use it in a app.blade.php file:

<x-guest-layout>

    @strand('NavBar', ['some' => 'data'])

    ...

    @nexus

</x-guest-layout>
Enter fullscreen mode Exit fullscreen mode

The NavBar component will be rendered and receive the props sent to it in the directive.

Final Thoughts

This is my first "big" project aimed to be used by the community, and it's just a side project. The project may contain flaws/bad choices (but who doesn't), or code that may cringe the hell out of you. Use it if you like, ignore it if you hate it.

PRs are welcome, but I may ignore them at my disclosure.

But hey, this is open-source, so you have my blessing (not that you need it anyway) to fork it and to do whatever the hell you want with it.

Top comments (0)