Reputation: 83
I have several generated pages with pagination listing all my blog posts, each blog post is generated from markdown using createPage(). Each generated /posts
page hold 3 Previews of the posts and following pages gets a number added posts/2
..etc
I want to pass the path of my current index page (which for instance can be /posts/3
) to the Blog page I click on, so I can make a "Back" Link on each of them. I can pass data using the state
attribute in the Link component, but I'm not sure passing the location.path from the list page with props is the proper way to go about since it doesn't work, it links to the actual current page.
I've omitted import-statements and unrelated code for readability.
gatsby-node.js
const { createPage } = actions
const blogPostTemplate = require.resolve(path.join(__dirname, `src`, `templates`, `blog-post-template.js`))
const blogListTemplate = require.resolve(path.join(__dirname, `src`, `templates`, `blog-list-template.js`))
const blogPosts = result.data.allMarkdownRemark.edges
// Create the list pages of the blog posts using the Awesome Pagination plugin
paginate({
createPage,
items: blogPosts,
itemsPerPage: 3,
pathPrefix: `/posts`,
component: blogListTemplate
})
// Create a page for each blog post
blogPosts.forEach(({ node }) => {
createPage({
path: node.frontmatter.slug,
component: blogPostTemplate,
context: {
slug: node.frontmatter.slug,
}
})
})
blog-list-template
const BlogListTemplate = ({ data, pageContext, location }) => {
const pathBack= location.pathname
return (
<Layout>
{posts.map(({ node }) => (
<Preview
key={node.id}
to={node.frontmatter.slug}
from={pathBack}
title={node.frontmatter.title}
date={node.frontmatter.date}
excerpt={node.excerpt}
/>
))}
</Layout>
)
}
preview.js
const Preview = ({ to, from, title, date, excerpt}) => {
console.log("This is preview: path ", from)
return(
<div>
<Link
to={to}
state={{ path: from}}
>
<h2>{title}</h2>
<p> - {date} - </p>
</Link>
<p>{excerpt}</p>
</div>
)
}
blog-post-template.js
const BlogPostTemplate = ({ data, path }) => {
return (
<Layout>
<div className="blogPost">
<Link to={path}>Tillbaka</Link>
<h1>{frontmatter.title}</h1>
<div className="blog-post-content" dangerouslySetInnerHTML={{__html: html}} />
<p>Publicerad: {frontmatter.date}</p>
</div>
</Layout>
Upvotes: 3
Views: 719
Reputation: 29320
Your approach is perfectly valid (and in my opinion is the easiest and cleanest). You are missing the props
destructuring to get the path
. Your code should look like:
const BlogPostTemplate = ({ data, location }) => {
return (
<Layout>
<div className="blogPost">
<Link to={location.state.path}>Tillbaka</Link>
<h1>{frontmatter.title}</h1>
<div className="blog-post-content" dangerouslySetInnerHTML={{__html: html}} />
<p>Publicerad: {frontmatter.date}</p>
</div>
</Layout>
I don't know if it's a typo, but frontmatter
will become undefined
, breaking your code in this snippet, I guess you are trying to do data.frontmatter
.
Note that everything that is sent via <Link>
's state, needs to be retrieved as props.location.state
, as you can see in the docs's example:
const PhotoFeedItem = ({ id }) => (
<div>
{/* (skip the feed item markup for brevity) */}
<Link
to={`/photos/${id}`}
state={{ fromFeed: true }}
>
View Photo
</Link>
</div>
)
const Photo = ({ location, photoId }) => {
if (location.state.fromFeed) {
return <FromFeedPhoto id={photoId} />
} else {
return <Photo id={photoId} />
}
}
Upvotes: 1