I've started messing around with Next JS, and I've come across my first hurdle. I am creating a page displaying a bunch of podcast episodes and I am displaying a little preview card for each podcast on the homepage. The card component looks something like this:
import React from 'react';
import Link from 'next/link';
import { kebabCase } from 'lodash';
import { format } from 'date-fns';
import TextTruncate from 'react-text-truncate';
import { Episode as EpisodeInterface } from '../../interfaces';
type Props = {
episode: EpisodeInterface;
};
const Episode: React.FunctionComponent<Props> = ({ episode }) => {
return (
<Link
href="episodes/[id]"
as={`episodes/${episode.itunes.episode}-${kebabCase(episode.title)}`}
>
<div className="group transition duration-500 cursor-pointer rounded-lg overflow-hidden shadow-lg border border-cream-darker bg-surface hover:bg-surface-hover hover:border-surface-hover hover:text-text-hover">
<div className="px-6 py-6">
<div className="font-bold font-serif text-3xl mb-2">
{episode.title}
</div>
<div className="transition duration-500 flex justify-between mb-2 text-gray-700 group-hover:text-text-hover">
<span>Episode {episode.itunes.episode}</span>
<span>{format(new Date(episode.isoDate), 'd MMMM yyyy')}</span>
</div>
<div className="mb-2">
<TextTruncate line={3} text={episode.contentSnippet} />
</div>
</div>
</div>
</Link>
);
};
export default Episode;
Now I want to be able to pass the episode
object to the full episode page located at /pages/episodes/[id].tsx
that is being linked to via the Link
element above, rather than have to refetch and filter all the episodes based upon the name of the route that I've chosen episodes/${episode.itunes.episode}-${kebabCase(episode.title)}
.
episode
object to the new view?You can't pass data to next/link component. Even if you would pass it, you won't be able to access it on server-side when a user visits the page directly or refreshes it.
To recap, if you need to pass data from Link through to the new component that's being rendered, pass Link s a state prop with the data you want to pass through. Then, to access the Link s state property from the component that's being rendered, use the useLocation Hook to get access to location. state .
When linking between pages on websites, you use the <a> HTML tag. In Next. js, you can use the Link Component next/link to link between pages in your application. <Link> allows you to do client-side navigation and accepts props that give you better control over the navigation behavior.
Adding to @AmerllicA's answer,
I found a way to pass props to the target page when clicking on a <Link>
component using getServerSideProps
Nextjs Link Component documentation https://nextjs.org/docs/api-reference/next/link
Nextjs getServerSideProps documentation https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering
You can pass a custom object to the query option of the href
prop
<Link
href={{
pathname: "episodes/[id]",
query: {
id: episode.itunes.episode,
title: episode.title
}
}}
as={`episodes/${episode.itunes.episode}-${kebabCase(episode.title)}`}
>
... button stuff
</Link>
in pages/episodes/[id].js
export const getServerSideProps= (context)=> {
console.log(context.query)
return {
props: {
title: context.query.title //pass it to the page props
}
}
}
export async function getServerSideProps (context) {
console.log(context.query)
// returns { id: episode.itunes.episode, title: episode.title}
//you can make DB queries using the data in context.query
return {
props: {
title: context.query.title //pass it to the page props
}
}
}
And can see the console.log
data in the terminal to confirm the data is passed
Finally, you can use the passed props in the episode screen
const Episode = (props) => {
return (
<div>{props.title}</div>
)
}
I think this would work with getStaticProps
as well.
Thank you for the question.
Actually, due to this link, it is an open issue and NextJS has no proper solution for it. Based on NexJS docs you can just pass query
params to the routed component. so I understand this is not a solution, but just right now it can fix your issue:
<Link href={{ pathname: '/about', query: { data: JSON.stringify(episode) } }}>
<a>About us</a>
</Link>
Then in the routed component get the query from URL and parse
it:
const RoutedComponent = () => {
useEffect(() => {
const { data } = getQueryParams(window.location.search);
}, []);
};
Note: the getQueryParams
is a simple function that returns all params data after the ?
in the URL.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With