gatsby-schema-field-absolute-path

This plugin resolves absolute path (i.e content/assets) to the correct File node in your Gatsby graphql schema.
For example, if you have a content structure like this
root
|--content
| |--posts
| | `--hello-world.md
| `--assets
| |--cat.jpg
| `--cat2.png
|--src
|--gatsby-config.js
...And in hello-world.md, you have this frontmatter
---
slug: hello-word
featuredImage: assets/cat.jpg
---
What a nice day!This plugin will resolve assets/cat.jpg to a File node instead of a string, so you can query the image as expected:
query PostContent {
frontmatter {
featuredImage {
childImageSharp {
fluid(maxWidth: 1280) {
...gatsbyImageSharpFluid
}
}
}
}
}Of course this is not done by magic, you’d have to add the generated field extension to your field via createTypes in gatsby-node.js.
// gatsby-node.js
exports.createSchemaCustomization = ({ actions }) => {
const { createTypes } = actions
// @fileByDataPath and @fileByAbsolutePath are
// field extensions generated by this plugin
const typeDefs = `
type Frontmatter @infer {
attachment: File @fileByAbsolutePath(path: "content/attachment")
}
${ /* Alternatively, define path via config. See options below */ }
type Frontmatter @infer {
featureImage: File @fileByDataPath
}
type MarkdownRemark implements Node @infer {
frontmatter: Frontmatter
}
`
createTypes(typeDefs)
}Multiple Images
Wait, what if you have an array of images instead?
slug: hello-word
- featuredImage: assets/cat.jpg
+ featuredImages:
+ - assets/cat.jpg
+ - assets/cat2.pngNo problems, just modify your gql slightly:
type Frontmatter @infer {
- featuredImage: File @fileByAbsolutePath(path: "content/assets")
+ featuredImages: [File] @fileByAbsolutePath(path: "content/assets")
}How It Works
I published a post on how this work over here: link
Usage
Install
yarn add gatsby-schema-field-absolute-path
# or
npm i gatsby-schema-field-absolute-pathAdd to Gatsby config
// gatsby-config.js
module.exports = {
plugins: [
// 1. No custom dirs
'gatsby-schema-field-absolute-path',
// 2. With custom dirs:
{
resolve: 'gatsby-schema-field-absolute-path',
options: {
// a. single directory
dirs: 'content/assets'
// b. array of directories
dirs: ['content/assets', 'src/processed/images']
// or c. object with named field extension
dirs: {
'content/assets': 'fileByAssetPath',
'src/processed/images': 'fileByImagePath',
}
}
}
]
}
Specify target fields
// gatsby-node.js
exports.createSchemaCustomization = ({ actions }) => {
const { createTypes } = actions
const typeDefs = `
type Frontmatter @infer {
${/* without configuration */}
featureImage: File @fileByAbsolutePath(path: "content/asset")
${/* or with configuration */}
featureImage: File @fileByAssetPath
}
type MarkdownRemark implements Node @infer {
frontmatter: Frontmatter
}
`
createTypes(typeDefs)
}How to Use
By default, this plugin create a generic field extension called fileByAbsolutePath. It accepts a path arguments, which allow finding file relative to the directory root:
root
|--content
| |--posts
| | `--hello-world.md
| `--assets
| `--cat.jpg
|--src
|--gatsby-config.js
...`
type Frontmatter @infer {
featuredImage: File @fileByAbsolutePath(path: "content/assets")
}
`You may also specify an option dirs, which accepts a string, an array of string, or an object. This plugin can generate multiple field extensions each targeting a specific directory, saving you some keystrokes if you have a lot of fields targeting files in different directories.
type Path = string
type FieldExtensionName = string
interface Options {
dirs: Path | Path[] | Record<Path, FieldExtensionName>
}- The path must be relative to your root directory. For example,
src//src/./srcwill all resolve to<project root>/src. - The field extension name is generated automatically by the directory:
| directory | generated field extension name |
|---|---|
content/posts |
pathByPostsPath |
content/assets |
pathByAssetsPath |
If you’re unsure what the generated name maybe, this plugin will tell you in development:
info gatsby-plugin-file-absolute-path: Field extension created! Use @fileByDataPath for 'src/data'- If you pass an object to
dir, you can specify the field extension name instead of generated one:
// option
dirs: { 'content/assets': 'myFieldExtensionName' }
// usage
`
type Frontmatter @infer {
featuredImage: File @myFieldExtensionName
}
`