Discussion of querying internal links in Sanity and using routes to separate pages for flexibility.
59 replies
Last updated: Apr 7, 2021
K
What I am hoping for is an object like this...
{ "_key": "c371572bc417", "_type": "internalLink", "item": { "_ref": "532b3294-5c63-42bd-9157-174796b2f706", "_type": "reference" }, "slug": "new-revolutionary-product" }
Apr 7, 2021, 12:59 AM
K
i think you are overcomplicating it,
could simply be
_type == "internalLink" => { ..., "slug": *[_type == "route" && page._ref == ^.item._ref]{slug} }
_type == "internalLink" => { ..., "slug": item->slug.current }
Apr 7, 2021, 1:02 AM
K
theres no need to do ^ inside of a reference expansion here
Apr 7, 2021, 1:02 AM
K
unless i am missing part of your data structure somewhere
Apr 7, 2021, 1:02 AM
K
Thank you, I'll try this too.
Apr 7, 2021, 1:04 AM
K
This returns NULL for the value.
Apr 7, 2021, 1:05 AM
K
what does your internal link object look like in your text block?
Apr 7, 2021, 1:06 AM
K
[ { "_key": "2fc431634c3b", "_type": "link", "href": "<https://bryanklein.com>" }, { "_key": "c371572bc417", "_type": "internalLink", "item": { "_ref": "532b3294-5c63-42bd-9157-174796b2f706", "_type": "reference" }, "slug": null } ]
Apr 7, 2021, 1:07 AM
K
i mean in like the text block in sanity not the query
Apr 7, 2021, 1:07 AM
K
annotations: [ { name: 'internalLink', type: 'object', icon: AiOutlineLink, title: 'Internal link', fields: [ { name: 'reference', type: 'reference', title: 'Reference', to: [ { type: 'page' }, { type: 'product' } ] }, { name: 'linkType', title: 'Link Type', type: "string", options: { list: [ { title: "Button", value: "button" }, { title: "Text", value: "text" }, { title: "Text + Arrow", value: "text-arrow" } ], layout: "dropdown" } } ] },
Apr 7, 2021, 1:07 AM
K
example
Apr 7, 2021, 1:07 AM
K
The schema for it?
Apr 7, 2021, 1:07 AM
K
yeah the text schema
Apr 7, 2021, 1:08 AM
K
import React from 'react'; const InternalLinkRender = ({ children }) => <span style={{backgroundColor:'lightblue'}}>{children}</span>; export default { title: 'Internal Link', name: 'internalLink', type: 'object', description: 'Locate a document you want to link to', fields: [ { name: 'item', type: 'reference', to: [{ type: 'page' }] } ], blockEditor: { icon: () => 'š', render: InternalLinkRender, }, };
Apr 7, 2021, 1:09 AM
G
what happens when you just try item-> without the additional notation
Apr 7, 2021, 1:09 AM
K
It returns the page object that the 'item' refers to, but it doesn't have a slug value.
Apr 7, 2021, 1:10 AM
K
"slug":{ "_createdAt": "2019-03-15T13:53:45Z", "_id": "532b3294-5c63-42bd-9157-174796b2f706", "_rev": "45Isps23253Yjlaq27Gb6c", "_type": "page", "_updatedAt": "2021-03-25T17:35:31Z", "content": [ { "_key": "e37000e4aea5", "_type": "hero", "backgroundImage": { "_type": "image", "asset": { "_ref": "image-99daef03a3557b742dd9de05e3b75aba0ad2a402-1350x900-png", "_type": "reference" } }, "heading": "We change industries!", "tagline": [ { "_key": "2f2895682c0b", "_type": "block", "children": [ { "_key": "2f2895682c0b0", "_type": "span", "marks": [], "text": "Disruptive implementations for the unknown future." } ], "markDefs": [], "style": "normal" } ] } ], "description": "This will change how you think about technology. We just need to figure out what it is first.", "openGraphImage": { "_type": "image", "asset": { "_ref": "image-99daef03a3557b742dd9de05e3b75aba0ad2a402-1350x900-png", "_type": "reference" } }, "title": "Our upcoming groundbreaking service" }
Apr 7, 2021, 1:11 AM
K
does that pageā¦ have a slug in the system?
Apr 7, 2021, 1:11 AM
K
Because in this example the slugs are stored in the 'routes' and not in the page.
Apr 7, 2021, 1:11 AM
K
gotcha so theres another level going on here
Apr 7, 2021, 1:12 AM
K
so you put all your pages in routes, and in the route you have a slug referencing the linked page
Apr 7, 2021, 1:12 AM
K
Exactly.
Apr 7, 2021, 1:12 AM
B
for stuff like this truthfully
*[_type == ārouteā && page._ref == ^.item._ref]
Apr 7, 2021, 1:13 AM
K
stick that in vision
Apr 7, 2021, 1:13 AM
K
with the proper item ref string
Apr 7, 2021, 1:13 AM
K
if it doesnāt work there something else might be going on
Apr 7, 2021, 1:13 AM
K
also i believe the ^ now fetches the proper parent and isnāt sub local anymore?
Apr 7, 2021, 1:14 AM
K
but i could be wrong depending on your api version
Apr 7, 2021, 1:14 AM
P
user A
was right about the naked projection. That works too. https://sanity-io-land.slack.com/archives/C011CAT70DD/p1617757304072500?thread_ts=1617756886.068900&cid=C011CAT70DD Apr 7, 2021, 1:14 AM
K
āØ
Apr 7, 2021, 1:14 AM
K
I was getting messed up with the {} thinking that I needed to wrap the projection with them.
Apr 7, 2021, 1:15 AM
K
(I am day 2 with groq, so please excuse my ignorance)
Apr 7, 2021, 1:15 AM
K
youāre doing something with routes iāve never seen
Apr 7, 2021, 1:16 AM
K
so kudos to whatever is going on there interested to see the why/how of it all
Apr 7, 2021, 1:16 AM
K
Yeah, it's a bit funky. That's what they are doing in the Sanity+Next.js+Netlify starter.
Apr 7, 2021, 1:16 AM
K
i wonder how they handled typed routes for like products/blogs etc there but i guess iāve never used that starter
Apr 7, 2021, 1:17 AM
G
Apr 7, 2021, 1:18 AM
K
Apr 7, 2021, 1:19 AM
K
dang thatās like super interesting, Iāll have to harass knut about this
Apr 7, 2021, 1:19 AM
G
Apr 7, 2021, 1:19 AM
K
this is potentially solving a like large complex data structure issue i have with a few projects. huge fan of hoping into this thread.
Apr 7, 2021, 1:20 AM
G
I was adding internal links into the rendering of the website and ran into this nested relationship. https://github.com/sanity-io/sanity-template-nextjs-landing-pages/blob/master/template/web/pages/LandingPage.js
Apr 7, 2021, 1:21 AM
G
yeah i mean this pattern absolutely adds complexity
Apr 7, 2021, 1:21 AM
G
but if wrangled seems very powerful
Apr 7, 2021, 1:22 AM
K
Where I have to start by querying the route and through it to the page I am on, then on down through the content/text/etc. to the links.
Apr 7, 2021, 1:22 AM
K
yeah youāll need to ensure you have the reference type too
Apr 7, 2021, 1:22 AM
G
the example currently only has a page* but imagining other routes that needed different nested structure
Apr 7, 2021, 1:22 AM
G
Yep, I think you would need different queries for each datatype.
Apr 7, 2021, 1:23 AM
G
Right now it is using the
pageQueryfor page data. But I could see something like that for different elements.
Apr 7, 2021, 1:24 AM
G
so this:
"slug": *[_type == "route" && page._ref == ^.item._ref][0].slug.current
Apr 7, 2021, 1:25 AM
K
you could open up to graph the type of the reference which is a deeper further nested query
Apr 7, 2021, 1:25 AM
G
Yeah, I would need to be careful with
page._ref
Apr 7, 2021, 1:25 AM
K
(depending on what you are after your life might be easier adding slugs to the page content type)
Apr 7, 2021, 1:27 AM
B
Yeah, I assume that this separation of the routes from the pages was to allow for some flexibility in what was presented in the sitemap, menus, etc.
Apr 7, 2021, 1:28 AM
G
Because there are toggles for that.
Apr 7, 2021, 1:29 AM
K
yeah
Apr 7, 2021, 1:29 AM
G
Thank you for jumping in to help on this. I spent too much time running into dead ends before I reached out.
Apr 7, 2021, 1:29 AM
G
Now I can do this in my serializer.
const serializers = { types: { embedHTML: EmbedHTML, figure: Figure }, marks: { internalLink: ({mark, children}) => { const href = `/${mark.slug}` return <a href={href}>{children}</a> }, link: ({mark, children}) => { // Read <https://css-tricks.com/use-target_blank/> const { blank, href } = mark return blank ? <a href={href} target="_blank" rel="noopener noreferer">{children}</a> : <a href={href}>{children}</a> } } }
Apr 7, 2021, 1:33 AM
K
Works like a charm. š
Apr 7, 2021, 1:34 AM
G
Apr 7, 2021, 1:34 AM
Sanityā build remarkable experiences at scale
Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.