Possible to send more info/props via generateStaticParams()?
Unanswered
Spectacled bear posted this in #help-forum
Spectacled bearOP
Is it possible to pass additional data in
By default
Currently I'm using this approach to generate custom routes where the keyword from the dynamic segment is included in the custom route ([figured out here](https://nextjs-forum.com/post/1182708886541697124#message-1182734381199134860)):
Problem:
So how can I send the
generateStaticParams() or during SSG of static pages?By default
generateStaticParams() only sends the keyword for the dynamic route to the page.Currently I'm using this approach to generate custom routes where the keyword from the dynamic segment is included in the custom route ([figured out here](https://nextjs-forum.com/post/1182708886541697124#message-1182734381199134860)):
export default function locationPage({params}) {
return <>
<h1>Doc in {params.pathname}</h1>
</>
}
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;
};Problem:
pathname in the locationPage() isn't cityName anymore but /doctor-in-${cityName}.So how can I send the
cityName along with the path name?35 Replies
use my answer, bard is wrong lol
if you want
cityName then it will be// 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,
}))
}@Ray if you want `cityName` then it will be
ts
// 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,
}))
}
Spectacled bearOP
Does this generate a URL like
domain.com/doctor-in-${cityName}?no need to combine with the middleware
@Ray no need to combine with the middleware
Spectacled bearOP
I just wonder that it seemed possible to simply send multiple props with pages router (like below).
And now with app router it's not easily possible anymore?
And now with app router it's not easily possible anymore?
import { AppRouter, Routes, Route } from 'next/router';
import { getStaticProps } from 'next';
const DoctorInCityPage = ({ cityName, additionalData }) => (
<div>
<h1>Doc in {cityName}</h1>
{additionalData && <p>Additional data: {additionalData.toString()}</p>}
</div>
);
export async function getStaticProps({ params }) {
const cityName = params.pathname.replace('/doctor-in-', '');
// Fetch additional data for the city
const additionalData = await fetchAdditionalData(cityName);
return {
props: {
cityName,
additionalData,
},
};
}
const App = () => (
<AppRouter>
<Routes>
<Route path="/doctor-in-{cityName}" element={<DoctorInCityPage />} />
</Routes>
</AppRouter>
);
export default App;you fetch the additionalData in the component
@Ray is this code from bard? never seem next/router render the route like this
Spectacled bearOP
yes, it's from bard.
but the point is that you could send multiple props using getStaticProps (pages router) but not with getStaticParams (app router) anymore.
and there seems nothing which replaces this feature in app router.
however, there's certainly another way to do it in app router.
but the point is that you could send multiple props using getStaticProps (pages router) but not with getStaticParams (app router) anymore.
and there seems nothing which replaces this feature in app router.
however, there's certainly another way to do it in app router.
because we don't need to pass to it anymore
we just fetch directly in the server component
@Ray you fetch the additionalData in the component
Spectacled bearOP
of course, you could do that.
would just be cool to have the city name passed to the pages correctly so that I can use it to fetch the remaining data.😇
would just be cool to have the city name passed to the pages correctly so that I can use it to fetch the remaining data.😇
like this
export default async function locationPage({params}) {
const additionalData = await fetchAdditionalData(params.cityName);
return <>
<h1>Doc in {params.cityName}</h1>
</>
}you were fetching inside
getStaticProps but with app router we fetch inside the server componentwith this
app/doctor-in/[cityName]/page.tsx path you get the cityName in the params objectthen the middleware will rewrite the url for you
domain/doctor-in-{cityName} -> domain/doctor-in/{cityName}
@Ray you were fetching inside `getStaticProps` but with app router we fetch inside the server component
Spectacled bearOP
I see.
Now the point is that I still want to get the URL like
And I'm not sure if I like the idea of rewriting the path (as in your middleware), because from what I understand the middleware will rewrite the URL only when the page gets visited.
Which means under the hood the URL is still something like
But the URL I want to communicate to search engines is
Now the point is that I still want to get the URL like
domain.com/doctor-in-${cityName} (which works when I construct the pathname using generateStaticParams (instead of just returning the cityName).And I'm not sure if I like the idea of rewriting the path (as in your middleware), because from what I understand the middleware will rewrite the URL only when the page gets visited.
Which means under the hood the URL is still something like
domain.com/doctor-in/${cityName} - which is the URL communicated to search engines.But the URL I want to communicate to search engines is
domain.com/doctor-in-${cityName}you generate the urls in sitemap
and you can also submit it in search console
google will crawl your site with your sitemap you submitted
or you can do this lol
// app/{doctorInCityName}/page.tsx
export default async function locationPage({params}) {
const cityName = params.doctorInCityName.replace('/doctor-in-', '');
const additionalData = await fetchAdditionalData(cityName);
return <>
<h1>Doc in {cityName}</h1>
</>
}then you dont need to rewrite the url in middleware
Spectacled bearOP
what about citynames with spaces and non-chars like:
Naumburg (saale) & Neuburg an der Donau?@Spectacled bear what about citynames with spaces and non-chars like: `Naumburg (saale)` & `Neuburg an der Donau`?
ideally you can retrieve the label of the cityName id from the database
so only the id is displayed in the URL, then you can retrieve the labels of the id in the Pages
so
/doctor-in-naumburgsaale will display Naumburg (saale) because when you find it in the database for id === naumburgsaale, it will return a label which is "Naumburg (saale)"@aardani so `/doctor-in-naumburgsaale` will display `Naumburg (saale)` because when you find it in the database for id === naumburgsaale, it will return a label which is "Naumburg (saale)"
Spectacled bearOP
so I would need to generate the "URL-safe" version (which you call label?) before-hand in the DB?
url-safe version is what i'd call the
idyeah
you can use slug for this to generate the url-safe version
Spectacled bearOP
Okay, thank you.
Need some time to try the different ways.😇
Need some time to try the different ways.😇
@Spectacled bear Okay, thank you.
Need some time to try the different ways.😇
cool, let us know which approach you ended up using!