am new to gatsby and graphql and I came across a tutorial where it is mentioned to fetch all the data using .map
. But I want to fetch only one element from the DB. So how do I do it?
import React from "react";
import Layout from "../components/layout";
import { useStaticQuery, graphql, Link } from "gatsby";
const Blogs = () => {
const data = useStaticQuery(
graphql`
query {
allMarkdownRemark(sort: { frontmatter: { date: ASC } }) {
edges {
node {
frontmatter {
title
date(formatString: "DD MM, YYYY")
}
excerpt
id
fields {
slug
}
}
}
}
}
`
);
return (
<Layout>
<ul>
{data.allMarkdownRemark.edges.map((edge) => {
return (
<li key={edge.node.id}>
<h2>
<Link to={`/blog/${edge.node.fields.slug}/`}>
{edge.node.frontmatter.title}
</Link>
</h2>
<div>
<span>
Posted on {edge.node.frontmatter.date}
</span>
</div>
<p>{edge.node.excerpt}</p>
<div>
<Link to={`/blog/${edge.node.fields.slug}/`}>Read More</Link>
</div>
</li>
);
})}
</ul>
</Layout>
);
};
export default Blogs;
Lets say I have multiple blogs and I wish to show only a specific one in a page through query like...
query MyQuery {
markdownRemark((id: {eq: "9ac19d6d"}) //Some ID {
title
description
content
}
}
How to get this on a page to display? Thanks in advance!
CodePudding user response:
With your query:
query MyQuery {
markdownRemark((id: {eq: "9ac19d6d"}) //Some ID {
title
description
content
}
}
Your data will be in data.markdownRemark
You can access those 3 fields directly.
const { title, description, content ] = data.markdownRemark;
return (
<Layout>
<div>
<p>{title}</p>
<p>{description]</p>
<p>{content}</p>
</div>
</Layout>
)
CodePudding user response:
Depending on what do you want to achieve:
If you want just a specific single post. You can filter your
useStaticQuery
to add the value of theid
(if you know it beforehand) like:query MyQuery { markdownRemark((id: {eq: "123"}) { title description content } }
useStaticQuery
as the name points out, is static and doesn't accept dynamic values.Another alternative is to get a specific position from
data.allMarkdownRemark
to display it.If you are trying to create dynamic posts, hence each post template will display a different blog post (one per template), you need to pass a filter value from
gatsby-node.js
(where you create the post pages) to the template through Gatsby's context:// gatsby-node.js posts.forEach(({ node }, index) => { createPage({ path: node.fields.slug, component: path.resolve(`./src/templates/blog-post.js`), context: { id: node.id, title: node.title }, }) })
Note: here I'm lifting the
id
and thetitle
. Use whatever works better for youNow, you can take advantage of the context in your
Blogs
component (as long as it's a template):const Blogs = ({data}) => { console.log("your blog post is:", data) return ( <Layout> <h1>{data.markdownRemark.title}</h1> </Layout> ); }; export const query = graphql` query($id: String!, $title: String!) { markdownRemark((id: {eq: $id}) { title description content } } ` export default Blogs;
In other words: the first approach uses a static query (via useStaticQuery
hook. Static, no dynamic parameters allowed) and the second uses a page query (only available in pages or templates)