Next.js Discord

Discord Forum

custom URLs possible?

Unanswered
Spectacled bear posted this in #help-forum
Open in Discord
Spectacled bearOP
Is it possible to generate custom URLs like bestDoc.com/doctor-in-{cityname}?
Something like bestDoc.com/doctor-in/{cityname} is easy and straightforward.
But not exactly what I want.

17 Replies

It is possible. You can get the searchparams and split them at „-„. Then you can extract the dynamic content. But keep in mind, that specific parts of your app are then dynamic @Spectacled bear
Spectacled bearOP
I feel misunderstood.
I want a URL-structure like bestDoc.com/doctor-in-{cityname}.
But cityname shouldn't even be dynamic.
Instead I want to generate dozens of static pages with this structure based on the cities which I have in my database.

How can I generate static pages with this URL structure during build, based on the cities in my database?
Spectacled bearOP
Bad solution I found so far are redirects in next.config.js:
/** @type {import('next').NextConfig} */
const nextConfig = {
    async redirects() {
        return [
            {
                source: '/doc-in/:location',
                destination: '/doc-in-:location',
                permanent: true,
            }
        ]
    }
}

module.exports = nextConfig

However this kills the whole purpose of making this SEO-optimized URL-structure.
Because search engines probably don't like redirects.😅
use generateStaticParams to generate the page
// app/doctor-in/[cityname]/page.tsx

export async function generateStaticParams() {
  const cities = await getCities() // get the cities from database
 
  return cities.map((city) => ({
    cityname: city.name,
  }))
}
then in middleware
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

export function middleware(request: NextRequest) {
  if (request.nextUrl.pathname.includes("doctor-in-")) {
    const cityname = request.nextUrl.pathname.split("-").at(-1);
    return NextResponse.rewrite(new URL(`/doctor-in/${cityname}`, request.url));
  }
}
when someone visit bestDoc.com/doctor-in-{cityname}, it will load the page at bestDoc.com/doctor-in/{cityname}
yea, what Ray said is also a possible solution. You can also make them dynamic (my solution) and specify all urls (rays solution) for SEO inside your sitemap. The search engine read that and know how to use your site 👍 @Spectacled bear
@Ray then in middleware ts import { NextResponse } from "next/server"; import type { NextRequest } from "next/server"; export function middleware(request: NextRequest) { if (request.nextUrl.pathname.includes("doctor-in-")) { const cityname = request.nextUrl.pathname.split("-").at(-1); return NextResponse.rewrite(new URL(`/doctor-in/${cityname}`, request.url)); } }
Spectacled bearOP
sounds reasonable.
From my understanding it would not just show the page at bestDoc.com/doctor-in/{cityname} but also this URL (instead of bestDoc.com/doctor-in-{cityname}, which is the desired one to make the google bot happy.
then the only thing I know is to do it via my method 🙂
Spectacled bearOP
Google Bard gave me this idea:
export const generateStaticParams = async () => {
  // Fetch the data for all cities from your database
  const allCitiesData = await getAllCitiesData();

  // Create an array of static page paths
  const paths = [];

  // Iterate through the cities and generate static page paths
  for (const city of allCitiesData) {
    const cityName = city.name;
    paths.push({ pathname: `/doctor-in-${cityName}` });
  }

  // Return the array of static page paths
  return paths;
};


This approach works fine by replacing the complete dynamic segment with your own string.
but how do you read the string on your page.js?
Spectacled bearOP
Not sure if I understand what you mean.
But this is my page.js:
export default function locationPage({params}) {
    return <>
        <h1>Doc in {params.pathname}</h1>
    </>
}

The dynamic route segment needs to be named [pathname]in order to work.
@Ray this is basically same as mine
Spectacled bearOP
Awesome @Ray and @B33fb0n3
Thanks a ton for your quick help🙏