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.png
No 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-path
Add 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
/./src
will 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
}
`