Reputation: 4211
I am trying to store content for a button that will navigate the user to a different page in my markdown frontmatter
, as it is to be editable through Netlify CMS.
When the GraphQL static query brings back data, my frontmatter has been converted into a relative file path rather than the intended page URL. This doesn't happen with page queries.
footer.md:
---
templateKey: footer
title: Some footer title
logo: /img/logo.svg
links:
- url: /prices/
text: Prices
- url: /privacy-policy/
text: Privacy policy
---
GraphQL static query:
const queryData = useStaticQuery(graphql`
query FooterComponent {
site {
siteMetadata {
title
}
}
markdownRemark(frontmatter: { templateKey: { eq: "footer" } }) {
frontmatter {
title
logo {
publicURL
}
links {
url
text
}
}
}
}
`);
Data that gets returned:
{
"title":"Some footer title",
"logo":{"publicURL":"/static/6731239d1e0c5fcdf0f825a8de82be10/logo.svg"},
"links":[
{"url":"../pages/prices","text":"Prices"},
{"url":"../pages/privacy-policy","text":"Privacy policy"}
]
}
You can see that the URL for the objects in the links array have been converted to relative file paths, rather than returning the actual link from the frontmatter as it is in the original markdown file.
How can I retrieve the actual link?
Upvotes: 0
Views: 592
Reputation: 11577
Reading your comment on the other answer, I think the issue is with fmImagesToRelative
. It keeps track of all created nodes, then tries to match each frontmatter field value with all file node's path.
A quickfix would to 'preserve' those frontmatter fields before running fmImagesToRelative
, then restore them afterward. So you would literally work around that function, like this:
exports.onCreateNode = ({ node }) => {
const isRemarkNode = node.internal.type === 'MarkdownRemark'
const originalFields = {}
if (isRemarkNode) {
Object.entries(node.frontmatter).forEach(([k, v]) => {
if (['links', 'some_other_field'].includes(k)) {
/* preserve */
originalFields[k] = v
/* remove the field to avoid unnecessary work */
delete node.frontmatter[k]
}
})
}
/* this function won't work without access to literally all nodes, hence why we leave it in the middle like this */
fmImagesToRelative(node)
if (isRemarkNode) {
/* restore */
node.frontmatter = {
...node.frontmatter,
...originalFields
}
}
}
Personally, I prefer to only modify fields that I know are files. With your example, I would rather declare that 'logo' is an image file, than excluding 'links'.
As a fellow NetlifyCMS user, I use createSchemaCustomization
to modify known file fields... It's rather complicated (as with anything Gatsby), so I wrote a plugin to simplify this.
So my approach would look like this:
exports.createSchemaCustomization = ({ actions }) => {
actions.createTypes(`
type Frontmatter @infer {
logo: File @fileByAbsolutePath(path: "static")
}
type MarkdownRemark implements Node @infer {
frontmatter: Frontmatter
}
`)
}
In the example above, @fileByAbsolutePath
is a field extension that takes logo
value (i.e img/logo.png
) & resolve it with static
, so when you query your markdown file you'd get a File node pointing to root/static/img/logo.png
.
It would be neat for fmImagesToRelative
to have exclude
/include
arguments, though I'm not a fan of the blanket approach.
Upvotes: 3