"Solving 'related posts' attached to page data at build time in Gatsby with Sanity"

13 replies
Last updated: Oct 20, 2021
šŸ‘‹ Trying to solve ā€œrelated postsā€ attached to page data at build time.
(We’re already generating category pages, showing posts referencing the category… but really struggling from the other direction.)
The problem is a reference only contains theĀ 
_key
,Ā 
_ref
, andĀ 
_type
Ā ...not the
_id
This write-up ALMOST works, but must be outdated…
https://nimblewebdeveloper.com/blog/gatsby-generate-related-posts-at-build-time

Also posted in the issue queue https://github.com/sanity-io/gatsby-source-sanity/issues/81#issuecomment-930521036

UPDATE:
_rawDataCategories
is the magic detail
.
Sep 29, 2021, 9:42 PM
Hi (again) Josh! I might just be misunderstanding you so perhaps a bit more detail would help, but when you say ā€œa reference only contains theĀ 
_key
,Ā 
_ref
, andĀ 
_type
Ā ...not theĀ 
_id
,ā€ I want to clarify that the
_ref
value is the
_id
of the target document.
Sep 29, 2021, 10:12 PM
Not the case for me. 😭 The
_ref
field is even a signed hash.
Example: tag id
f9701e5b-3434-4c8d-9280-52b2a1dfea87
comes back as
_ref: '-468e50a2-1a86-5b51-b5a6-78e87ea4fc32'

I’ve tried using both
createSchemaCustomization
and
createResolvers
to attach the query.
Sep 29, 2021, 10:41 PM
gatsby-source-sanity
7.0.2
Sep 29, 2021, 10:44 PM
(GraphQL)
Sep 29, 2021, 10:51 PM
šŸŖ„āœØ You must use
_rawDataCategories
to get the
id
via
_ref
otherwise it’s that reference hash instead.
Sep 30, 2021, 12:52 AM
I should probably make a snippet out of this.
Sep 30, 2021, 12:52 AM
hey
user Q
I was looking into the same article you shared above and didn’t manage to make it work. keep getting an empty array for
related
. I also triple check that I dont have any
_rawDataCategories
to get the
id
via
ref
. Any pointer? šŸ™šŸ™‡ā€ā™‚ļø
Oct 18, 2021, 3:09 PM
exports.createSchemaCustomization = ({ actions, schema }) => {
  actions.createTypes([
    schema.buildObjectType({
      interfaces: ["Node"],
      name: "SanityPost",
      fields: {
        relatedPosts: {
          type: "[SanityPost]",
          resolve: async (source, args, context, info) => {
            const categories = source._rawDataCategories
              ? source._rawDataCategories.map((c) => c._ref)
              : [];
            if (!categories.length) return [];

            const posts = await context.nodeModel.runQuery({
              query: {
                filter: {
                  categories: {
                    elemMatch: {
                      _id: { in: categories },
                    },
                  },
                  // exclude current node
                  _id: { ne: source._id },
                },
                // no way to limit results in runQuery
                // see: <https://github.com/gatsbyjs/gatsby/issues/15453>
              },
              type: "SanityPost",
            });

            return posts &amp;&amp; posts.length &gt; 0 ? posts : [];
          },
        },
      },
    })
  ]);
};
Oct 18, 2021, 5:31 PM
Then be sure to put
relatedPosts
into your page query as if it was another field (with subfields of course).
Oct 18, 2021, 5:33 PM
For clarity, that goes in
gatsby-node.js
and you’ll probably want this too…

sort: {
  fields: ["publishedAt"],
  order: ["DESC"],
},
Oct 18, 2021, 8:50 PM
For clarity, that goes in
gatsby-node.js
and you’ll probably want this too…

sort: {
  fields: ["publishedAt"],
  order: ["DESC"],
},
Oct 18, 2021, 8:50 PM
THANK YOU SO MUCH THIS WORKS LIKE A CHARM!
user Q
Oct 20, 2021, 3:30 PM
Oct 20, 2021, 6:34 PM

Sanity– build remarkable experiences at scale

The Sanity Composable Content Cloud is the headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?