Learn Laravel Routing Techniques for Next.js

lokman musliu
Lokman Musliu

February 16, 2023 · 4 min read · 856 views

Code Editor Blogpost Image

Understanding Laravel Routing Techniques

At the heart of our development endeavors, Laravel remains our preferred backend framework for its intuitiveness and reliability. One of Laravel's standout features is its effortless route definition, which significantly simplifies the process of making requests from the front end of your application.

For those who haven't yet experienced the ease of Laravel, here's a straightforward example to illustrate:

<?php

use Illuminate\Support\Facades\Route;

Route::get('/blog/{slug}', [BlogController::class, 'show'])->name('blog.show');

Imagine you've established a route for your blog post, resulting in a URL like this:

/blog/this-is-my-first-post.

When we want to show a list of posts on the front end of our Laravel application, we can use Laravel's route helper to get the full URL—it's so convenient!

@foreach($posts as $post)
  <a href="{{ route('blog.show', $post->slug) }}">
	{{ $post->title }}
  </a>
@endforeach

When it's time to showcase a collection of blog posts on the front end of your Laravel application, the framework's built-in route helper comes to the rescue. It effortlessly retrieves the complete URL for each post—talk about convenience!

What's more, should the need arise to modify a route, you only need to make the change in a single location. The front end will sync up with the update automatically, demonstrating the simplicity and clarity of Laravel's routing system.

Integrating Next.js for Front End Magic

For our website, we've chosen Next.js as our framework and paired it with a Headless CMS for content management.

Next.js introduces us to the world of file-based routing, which we employ for our blog section, adopting the pattern blog/[slug].js.

Here, 'slug' represents a dynamic segment of the route. By harnessing Next.js's powerful functions like getStaticPaths and getStaticProps, we can render all our blog posts under this dynamic route with ease. This approach not only maintains a clean and organized structure but also enhances the performance and scalability of our application.

The Problem

On our Blog Index page, there is a React component that lists all the blog posts.

import Heading from '@/components/Heading';
import Layout from '@/layout/Layout';

export default function BlogIndex({ posts }) {
  return (
    <Layout title="Blog">
      <Heading>Blog</Heading>

      <div className="container py-32">
        <div className="flex flex-wrap">
          {posts.map((blog, index) => {
            return (
              <Link key={index} href={`/blog/${blog.slug}`}>
                {blog.title}
              </Link>
            );
          })}
        </div>
      </div>
    </Layout>
  );
}

To get the routing for a single blog post, we have to use template literals, as you can see here:

href={`/blog/${blog.slug}`}.

There are quite a few issues with this approach:

  • It's not easily readable and prone to typing errors.

  • If we make a typo, we have to actually visit the route for Next.js to throw a 404 error.

  • If this route is used in multiple components, we'll have to update all of those files if the route ever changes.

  • It looks pretty ugly ❌

Coming from a Laravel background, we want a simpler and cleaner approach—as we mentioned in the first example. Fortunately, there's a way to do that with just a few lines of code.

First, we can set up a routes.js file in the root folder. We can define all our dynamic routes that the front end needs.

export const routes = {
  'blog.index': {
    path: '/blog',
  },
  'blog.show': {
    path: '/blog/{slug}',
  },
  'case-studies.index': {
    path: '/case-studies',
  },
  'case-studies.show': {
    path: '/case-studies/{slug}',
  },
  'careers.index': {
    path: '/careers',
  },
  'careers.show': {
    path: '/careers/{slug}',
  },
};

Now that we have our routes.js file in place, we need a route helper that will take our route name and generate the appropriate URL along with the parameters. Have a look at the route.js helper file:

import { routes } from '../routes';

const route = (name, params = {}) => {
 
  if (! routes[name]) {
    throw new Error(
      `Route ${name} not found. Make sure you have added it to the routes.js file.`
    );
  }

  const url = routes[name];

  if (!params) {
    return url.path;
  }

  return Object.keys(params).reduce((path, key) => {
    return path.replace(`{${key}}`, params[key]);
  }, url.path);
};

export default route;

Now with our route helper in place, look at the before and after when linking to blog posts:

import route from '@/utils/route';

const Before = ({ blog }) => (
  <Link href={`/blog/${blog.slug}`}>
    {blog.title}
  </Link>
)

const After = ({ blog }) => (
  <Link href={route('blog.show', { slug: blog.slug })}>
    {blog.title}
  </Link>
)

We can make this simpler by destructuring the blog object. Here's the final BlogIndex page with the new route helper:

import Heading from '@/components/Heading';
import Layout from '@/layout/Layout';
import route from '@/utils/route';

export default function BlogIndex({ posts }) {
  return (
    <Layout title="Blog">
      <Heading>Blog</Heading>

      <div className="container py-32">
        <div className="flex flex-wrap">
          {posts.map(({ title, slug }, index) => {
            return (
              <Link key={index} href={route('blog.show', { slug })}>
                {title}
              </Link>
            );
          })}
        </div>
      </div>
    </Layout>
  );
}

Routing has become a breeze with Laravel's route helper at our disposal. This invaluable tool clarifies URL structures and parameters, making it a cinch for developers to pinpoint the exact paths they need to work with. Should the time come to modify any routes, the solution is straightforward: simply update the routes.js file located in the root directory. The route helper handles everything else, ensuring that changes are reflected throughout the application without additional manual updates.

The route helper's versatility extends to handling multiple parameters as well, showcasing its adaptability to complex routing scenarios:

// routes.js
export const routes = {
  'blog.tags': {
    path: '/blog/{tags}/{slug}',
  },
}

// In our Category Index
route('blog.tags', {
  tags: 'react',
  slug: 'hello-world-in-react'
})

/* 
*
This will render the following url:

/blog/react/hello-world-in-react

*/

Final Reflections on Next.js and Routing

While navigating the routing landscape of Next.js may present its challenges, the integration of a route helper can significantly demystify the process. With this tool, linking to routes within your application is not only more intuitive but also faster and more efficient. Embrace the simplicity that the route helper brings to your routing strategy, and watch as it transforms the maintenance and scalability of your Next.js projects.


Bring Your Ideas to Life 🚀

If you need help with a Laravel project let's get in touch.

Lucky Media is proud to be recognized as a Top Laravel Development Agency and Next.js Development

lokman musliu
Lokman Musliu

Founder and CEO of Lucky Media

Technologies:

Next.js
Laravel
Heading Pattern

Related Posts

Stay up to date

Be updated with all news, products and tips we share!