diff --git a/docs/docs/how-to/images-and-media/working-with-images-in-markdown.md b/docs/docs/how-to/images-and-media/working-with-images-in-markdown.md new file mode 100644 index 0000000000000..1af1b04b18989 --- /dev/null +++ b/docs/docs/how-to/images-and-media/working-with-images-in-markdown.md @@ -0,0 +1,242 @@ +--- +title: Working with Images in Markdown & MDX +--- + +When building Gatsby sites composed primarily of [markdown](/docs/how-to/routing/adding-markdown-pages/) or [MDX](/docs/how-to/routing/mdx/), insertion of images can enhance the content. You can add images in multiple ways which will be explained below. If you're new to Gatsby we recommend checking out the [main tutorial](/docs/tutorial/) first. The instructions also assume that you already have an existing Gatsby site running with either markdown or MDX. + +## Prerequisites + +- A Gatsby project set up. (Need help creating one? Follow the [Quick Start](/docs/quick-start/)) +- Either markdown or MDX support added to your site. Follow the [MDX instructions](/docs/how-to/routing/mdx/) or [markdown instructions](/docs/how-to/routing/adding-markdown-pages/). + +## Featured images with frontmatter metadata + +In sites like a blog, you may want to include a featured image that appears at the top of a page. One way to do this is to grab the image filename from a frontmatter field and then transform it with `gatsby-plugin-sharp` in a GraphQL query. + +If you want to have a very detailed explanation of this, head to [part 7 of the Gatsby tutorial](/docs/tutorial/part-7/). The tutorial uses MDX, the instructions below will use markdown for the most part. It more or less behaves the same though. + +To start out, install the necessary plugins for [gatsby-plugin-image](/docs/how-to/images-and-media/using-gatsby-plugin-image/). + +```shell +npm install gatsby-plugin-image gatsby-plugin-sharp gatsby-source-filesystem gatsby-transformer-sharp +``` + +Then, configure the various plugins in the `gatsby-config` file. + +### Configuring for images and posts in the same directory + +If your images are in the same directory as the markdown files, sourcing and resolving the images can be done in one configuration. For example, if your markdown files and images are located together in a `src/content` directory, both content types will be automatically picked up by GraphQL as part of Gatsby's data layer. + +```js:title=gatsby-config.js +module.exports = { + plugins: [ + `gatsby-plugin-sharp`, + `gatsby-transformer-sharp`, + `gatsby-transformer-remark`, + `gatsby-plugin-image`, + { + resolve: `gatsby-source-filesystem`, + options: { + path: `${__dirname}/src/content`, // highlight-line + }, + }, + ], +} +``` + +Then, in an example markdown file, add a field called `featuredImage`: + +```markdown:title=src/content/my-favorite-doggos.md +--- +title: My Favorite Doggos +featuredImage: pupperino.png +--- + +Content goes here! +``` + +The next step will be to incorporate the data into a template with a GraphQL query, which can be found later in this guide. + +### Configuring for images and posts in different directories + +There are also occasions when you may want to source images from a different directory than where your markdown posts or pages are located, such as in an external `/images` folder. You can set this up by specifying two distinct sources, one for the markdown files and the other for images: + +```js:title=gatsby-config.js +module.exports = { + plugins: [ + `gatsby-plugin-sharp`, + `gatsby-transformer-sharp`, + `gatsby-transformer-remark`, + `gatsby-plugin-image`, + { + resolve: `gatsby-source-filesystem`, + options: { + path: `${__dirname}/src/content`, // highlight-line + }, + }, + { + resolve: `gatsby-source-filesystem`, + options: { + path: `${__dirname}/src/images`, // highlight-line + }, + }, + ], +} +``` + +Then, in a markdown file, the path to a `featuredImage` would be relative to the page file (in this case, in an `/images` directory up a level): + +```markdown:title=src/content/about.md +--- +title: About +featuredImage: ../images/team-cat.png +--- + +Content goes here! +``` + +### Querying for images from frontmatter + +Now that you've sourced markdown and image data, you can query for featured images in GraphQL. If a filepath points to an actual image, it will be transformed into a `File` node in GraphQL and then you can get the image data out of it by using the `childImageSharp` field. + +This can be added to the GraphQL query in a markdown template file. In this example, a [Dynamic image](/docs/how-to/images-and-media/using-gatsby-plugin-image/#dynamic-images) is used to make a responsive image. The query below might be different to what you have in your blog post template, however the highlighted section will be relevant nevertheless: + +```jsx:title=src/templates/blog-post.jsx +export const query = graphql` + query PostQuery($id: String) { + markdownRemark(id: { eq: $id }) { + html + frontmatter { + title + // highlight-start + featuredImage { + childImageSharp { + gatsbyImageData(width: 800) + } + } + // highlight-end + } + } + } +` +``` + +In the blog post template, import the `gatsby-plugin-image` package and pass the results of the GraphQL query into an `` component. + +```jsx:title=src/templates/blog-post.jsx +import * as React from "react" +import { graphql } from "gatsby" +// highlight-start +import { GatsbyImage, getImage } from "gatsby-plugin-image" +// highlight-end + +export default function BlogPost({ data }) { + let post = data.markdownRemark + + // highlight-start + let featuredImg = getImage(post.frontmatter.featuredImage?.childImageSharp?.gatsbyImageData) + // highlight-end + + return ( +
+

{post.frontmatter.title}

+ // highlight-start + + // highlight-end +
+
+ ) +} + +export const query = graphql` + query PostQuery($id: String) { + markdownRemark(id: { eq: $id }) { + html + frontmatter { + title + featuredImage { + childImageSharp { + gatsbyImageData(width: 800) + } + } + } + } + } +` +``` + +The code example above is just an example, adjust the `` portion to how you'd want to use it in your template. + +## Inline images with `gatsby-remark-images` + +You may also include images in the markdown/MDX body itself. The plugin [gatsby-remark-images](/plugins/gatsby-remark-images) comes in handy for this. + +Start out by installing `gatsby-remark-images`: + +```shell +npm install gatsby-remark-images +``` + +Configure the plugins in your `gatsby-config` file. As with the previous example, either markdown or MDX can be used. + +### Using `gatsby-transformer-remark` + +Put the `gatsby-remark-images` plugin within the `plugins` option field of `gatsby-transformer-remark`. + +```js:title=gatsby-config.js +module.exports = { + plugins: [ + // Rest of the plugins... + { + resolve: `gatsby-transformer-remark`, + options: { + plugins: [ + { + resolve: `gatsby-remark-images`, + options: { + maxWidth: 800, + }, + }, + ], + }, + }, + ], +} +``` + +### Using `gatsby-plugin-mdx` + +`gatsby-remark-images` needs to be a sub-plugin of `gatsby-plugin-mdx`, included in the `gatsbyRemarkPlugins` array. + +```js:title=gatsby-config.js +module.exports = { + plugins: [ + // Rest of your plugins... + { + resolve: `gatsby-plugin-mdx`, + options: { + gatsbyRemarkPlugins: [ + { + resolve: `gatsby-remark-images`, + options: { + maxWidth: 1200, + }, + }, + ], + }, + }, + ], +} +``` + +With the configurations above, you can use the default markdown syntax for images. They will be processed by sharp and appear as if you placed them in a `gatsby-plugin-image` component. + +```markdown +![Hopper The Rabbit](./rabbit-friend.png) +``` + +## Additional Resources + +- [Using gatsby-plugin-image](/docs/how-to/images-and-media/using-gatsby-plugin-image/) +- [Adding MDX pages](/docs/how-to/routing/mdx/) +- [Adding markdown pages](/docs/how-to/routing/adding-markdown-pages/) diff --git a/docs/docs/how-to/routing/adding-markdown-pages.md b/docs/docs/how-to/routing/adding-markdown-pages.md index e094675e5e878..5f1221a5a35bd 100644 --- a/docs/docs/how-to/routing/adding-markdown-pages.md +++ b/docs/docs/how-to/routing/adding-markdown-pages.md @@ -1,74 +1,83 @@ --- title: Adding Markdown Pages examples: - - label: Using gatsby-transformer-remark + - label: using-remark href: "https://github.com/gatsbyjs/gatsby/tree/master/examples/using-remark" --- -Gatsby can use Markdown files to create pages in your site. -You add plugins to read and understand folders with Markdown files and from them create pages automatically. +Gatsby can use markdown files to create pages in your site. You add plugins to read and understand folders with markdown files and from them create pages automatically. Here are the steps Gatsby follows for making this happen. 1. Read files into Gatsby from the filesystem -2. Transform Markdown to HTML and [frontmatter](#frontmatter-for-metadata-in-markdown-files) to data -3. Add a Markdown file -4. Create a Collection Route component for the Markdown files +1. Transform markdown to HTML and [frontmatter](#frontmatter-for-metadata-in-markdown-files) to data +1. Add a markdown file +1. Create a collection route component for the markdown files -## Read files into Gatsby from the filesystem +## Prerequisites -Use the plugin [`gatsby-source-filesystem`](/plugins/gatsby-source-filesystem/#gatsby-source-filesystem) to read files. +- A Gatsby project set up. (Need help creating one? Follow the [Quick Start](/docs/quick-start/)) -### Install +## Instructions -`npm install gatsby-source-filesystem` +### Read files into Gatsby from the filesystem -### Add plugin +Use the plugin [`gatsby-source-filesystem`](/plugins/gatsby-source-filesystem/#gatsby-source-filesystem) to read files and let Gatsby create `File` nodes in its GraphQL data layer. Install it like so: -Open `gatsby-config.js` to add the `gatsby-source-filesystem` plugin. The `path` option is how you set the directory to search for files. +```shell +npm install gatsby-source-filesystem +``` -```javascript:title=gatsby-config.js +Open `gatsby-config` to add the `gatsby-source-filesystem` plugin. The `path` option is how you set the directory to search for files. + +```js:title=gatsby-config.js module.exports = { - siteMetadata: { - title: "My Gatsby Site", - }, plugins: [ { resolve: `gatsby-source-filesystem`, options: { - name: `markdown-pages`, - path: `${__dirname}/src/markdown-pages`, + name: `content`, + path: `${__dirname}/src/content`, }, }, ], } ``` -Completing the above step means that you've "sourced" the Markdown files from the filesystem. You can now "transform" the Markdown to HTML and the YAML frontmatter to JSON. +Create a folder in the `src` directory of your Gatsby application called `content`. Now create a markdown file inside it with the name `post-1.md`. -## Transform Markdown to HTML and frontmatter to data using `gatsby-transformer-remark` +When you create a markdown file, you can include a set of key/value pairs that can be used to provide additional data relevant to specific pages in the GraphQL data layer. This data is called _frontmatter_ and is denoted by the triple dashes at the start and end of the block. This block will be parsed by `gatsby-transformer-remark` as YAML. You can then query the data through the GraphQL API from your React components. -You'll use the plugin [`gatsby-transformer-remark`](/plugins/gatsby-transformer-remark/) to recognize files which are Markdown and read their content. The plugin will convert the frontmatter metadata part of your Markdown files as `frontmatter` and the content part as HTML. +```md:title=src/content/post-1.md +--- +slug: "/my-first-blog-post" +date: "2022-11-24" +title: "My first blog post" +--- +``` -### Install transformer plugin +What is important in this step is the key pair `slug`. The value that is assigned to the key `slug` is used for the final URL of the post. -`npm install gatsby-transformer-remark` +Completing the above step means that you've _sourced_ the markdown files from the filesystem. You can now _transform_ the markdown to HTML and the YAML frontmatter to JSON. -### Configure plugin +### Transform markdown to HTML and frontmatter to data using `gatsby-transformer-remark` -Add this to `gatsby-config.js` after the previously added `gatsby-source-filesystem`. +You'll use the plugin [`gatsby-transformer-remark`](/plugins/gatsby-transformer-remark/) to recognize files which are markdown and read their content. The plugin will convert the frontmatter metadata part of your markdown files as `frontmatter` and the content part as HTML. Install the plugin: + +```shell +npm install gatsby-transformer-remark +``` + +Add this to `gatsby-config` after the previously added `gatsby-source-filesystem`. ```javascript:title=gatsby-config.js module.exports = { - siteMetadata: { - title: "My Gatsby Site", - }, plugins: [ { resolve: `gatsby-source-filesystem`, options: { - name: `markdown-pages`, - path: `${__dirname}/src/markdown-pages`, + name: `content`, + path: `${__dirname}/src/content`, }, }, // highlight-next-line @@ -77,45 +86,25 @@ module.exports = { } ``` -## Add a Markdown file +## Create a collection route for the markdown files -Create a folder in the `/src` directory of your Gatsby application called `markdown-pages`. -Now create a Markdown file inside it with the name `post-1.md`. +Use the [File System Route API](/docs/reference/routing/file-system-route-api/) to create a collection route (you can learn all details in the linked document). Create `src/pages/blog/{markdownRemark.frontmatter__slug}.jsx` and add the following code: -### Frontmatter for metadata in Markdown files - -When you create a Markdown file, you can include a set of key/value pairs that can be used to provide additional data relevant to specific pages in the GraphQL data layer. This data is called "frontmatter" and is denoted by the triple dashes at the start and end of the block. This block will be parsed by `gatsby-transformer-remark` as YAML. You can then query the data through the GraphQL API from your React components. - -```markdown:title=src/markdown-pages/post-1.md ---- -slug: "/blog/my-first-post" -date: "2019-05-04" -title: "My first blog post" ---- -``` - -What is important in this step is the key pair `slug`. The value that is assigned to the key `slug` is used in order to navigate to your post. - -## Create a Collection Route for the Markdown files - -Create `src/pages/{MarkdownRemark.frontmatter__slug}.js` and add the following code: - -```jsx:title=src/pages/{MarkdownRemark.frontmatter__slug}.js -import React from "react" +```jsx:title=src/pages/blog/{markdownRemark.frontmatter__slug}.jsx +import * as React from "react" import { graphql } from "gatsby" -export default function Template({ +export default function BlogPostTemplate({ data, // this prop will be injected by the GraphQL query below. }) { const { markdownRemark } = data // data.markdownRemark holds your post data const { frontmatter, html } = markdownRemark return ( -
-
+
+

{frontmatter.title}

{frontmatter.date}

@@ -137,24 +126,19 @@ export const pageQuery = graphql` ` ``` -Two things are important in the file above: - -1. A GraphQL query is made in the second half of the file to get the Markdown data. Gatsby has automagically given you all the Markdown metadata and HTML in this query's result. +When you now start `gatsby develop`, you should be able to navigate to `localhost:8000/blog/my-first-blog-post`. - **Note: To learn more about GraphQL, consider this [excellent resource](https://www.howtographql.com/)** - -2. The result of the query is injected by Gatsby into the component as the `data` prop. `props.data.markdownRemark` is the property that has all the details of the Markdown file. - -Next you could create a page component at `src/pages/blog/index.js` to serve as a listing page for all your blog posts. +Two things are important in the file above: -This should get you started on some basic Markdown functionality in your Gatsby site. You can further customize the frontmatter and the component file to get desired effects! +1. A GraphQL query is made in the second half of the file to get the markdown data. Gatsby has automagically given you all the markdown metadata and HTML in this query's result. You can learn more about [page queries](/docs/how-to/querying-data/page-query/) if you're interested. -For more information, have a look in the working example `using-markdown-pages`. You can find it in the [Gatsby examples section](https://github.com/gatsbyjs/gatsby/tree/master/examples). +1. The result of the query is injected by Gatsby into the component as the `data` prop. `props.data.markdownRemark` is the property that has all the details of the markdown file. -## Other tutorials +Next you could create a page component at `src/pages/blog/index.jsx` to serve as a listing page for all your blog posts. -Check out tutorials listed on the [Awesome Gatsby](/docs/awesome-gatsby-resources/#gatsby-tutorials) page for more information on building Gatsby sites with Markdown. +This should get you started on some basic markdown functionality in your Gatsby site. You can further customize the frontmatter and the component file to get desired effects! -## Gatsby Markdown starters +## Additional Resources -There are also a number of [Gatsby starters](/starters?c=Markdown) that come pre-configured to work with Markdown. +- [Working with images in markdown & MDX](/docs/how-to/images-and-media/working-with-images-in-markdown/) +- [Markdown syntax](/docs/reference/markdown-syntax/) diff --git a/docs/docs/working-with-images-in-markdown.md b/docs/docs/working-with-images-in-markdown.md deleted file mode 100644 index dd3b14482ccc9..0000000000000 --- a/docs/docs/working-with-images-in-markdown.md +++ /dev/null @@ -1,258 +0,0 @@ ---- -title: Working with Images in Markdown Posts and Pages ---- - -When building Gatsby sites composed primarily of Markdown pages or posts, insertion of images can enhance the content. You can add images in multiple ways. - -## Featured images with Frontmatter metadata - -In sites like a blog, you may want to include a featured image that appears at the top of a page. One way to do this is to grab the image filename from a frontmatter field and then transform it with `gatsby-plugin-sharp` in a GraphQL query. - -This solution assumes you already have programmatically generated pages from Markdown with renderers like `gatsby-transformer-remark` or `gatsby-plugin-mdx`. If not, take a read through up to [Part 7 of the Gatsby Tutorial](/docs/tutorial/part-7/). This will build upon the tutorial and as such, `gatsby-transformer-remark` will be used for this example. - -> Note: This can be done similarly using [MDX](/docs/how-to/routing/mdx/) as well. Instead of the `markdownRemark` nodes in GraphQL, `Mdx` can be swapped in and should work. - -To start out, download the plugins for Gatsby-image as mentioned in [Using gatsby-image](/docs/how-to/images-and-media/using-gatsby-image/). - -```shell -npm install gatsby-image gatsby-transformer-sharp gatsby-plugin-sharp -``` - -You will also want to have `gatsby-source-filesystem` installed. Then, configure the various plugins in the `gatsby-config` file. - -### Configuring for images and posts in the same directory - -If your images are in the same directory as the Markdown files, sourcing and resolving the images can be done in one configuration. For example, if your Markdown pages and images are located together in a `/pages` directory, both content types will be automatically picked up by GraphQL as part of Gatsby's data layer. - -```js:title=gatsby-config.js -module.exports = { - plugins: [ - `gatsby-plugin-sharp`, - `gatsby-transformer-sharp`, - `gatsby-transformer-remark`, - { - resolve: `gatsby-source-filesystem`, - options: { - path: `${__dirname}/src/pages`, // highlight-line - }, - }, - ], -} -``` - -Then, in an example Markdown file, add a field called `featuredImage`: - -```markdown:title=src/pages/my-favorite-doggos.md ---- -title: My Favorite Doggos -featuredImage: pupperino.png ---- - -Content goes here! -``` - -The next step will be to incorporate the data into a template with a GraphQL query, which can be found later in this guide. - -### Configuring for images and posts in different directories - -There are also occasions when you may want to source images from a different directory than where your Markdown posts or pages are located, such as in an external `/images` folder. You can set this up by specifying two distinct sources, one for the pages and the other for images: - -```js:title=gatsby-config.js -module.exports = { - plugins: [ - `gatsby-plugin-sharp`, - `gatsby-transformer-sharp`, - `gatsby-transformer-remark`, - { - resolve: `gatsby-source-filesystem`, - options: { - path: `${__dirname}/src/pages`, // highlight-line - }, - }, - { - resolve: `gatsby-source-filesystem`, - options: { - path: `${__dirname}/src/images`, // highlight-line - }, - }, - ], -} -``` - -Then, in a Markdown file, the path to a `featuredImage` would be relative to the page file (in this case, in an `/images` directory up a level): - -```markdown:title=src/pages/about.md ---- -title: About -featuredImage: ../images/team-cat.png ---- - -Content goes here! -``` - -### Querying for images from Frontmatter - -Now that you've sourced Markdown and image data, you can query for featured images in GraphQL. If a filepath points to an actual image, it will be transformed into a `File` node in GraphQL and then you can get the image data out of it by using the `childImageSharp` field. - -This can be added to the GraphQL query in a Markdown template file. In this example, a [Fluid query](/docs/reference/built-in-components/gatsby-image#images-that-stretch-across-a-fluid-container) is used to make a responsive image. - -```jsx:title=src/templates/blog-post.js -export const query = graphql` - query PostQuery($slug: String!) { - markdownRemark(fields: { slug: { eq: $slug } }) { - html - frontmatter { - title - // highlight-start - featuredImage { - childImageSharp { - fluid(maxWidth: 800) { - ...GatsbyImageSharpFluid - } - } - } - // highlight-end - } - } - } -` -``` - -Also in the Markdown post template, import the `gatsby-image` package and pass the results of the GraphQL query into an `` component. - -```jsx:title=src/templates/blog-post.js -import React from "react" -import { graphql } from "gatsby" -import Layout from "../components/layout" -// highlight-start -import Img from "gatsby-image" -// highlight-end - -export default function BlogPost({ data }) { - let post = data.markdownRemark - - // highlight-start - let featuredImgFluid = post.frontmatter.featuredImage.childImageSharp.fluid - // highlight-end - - return ( - -
-

{post.frontmatter.title}

- // highlight-start - - // highlight-end -
-
- - ) -} - -export const query = graphql` - query PostQuery($slug: String!) { - markdownRemark(fields: { slug: { eq: $slug } }) { - html - frontmatter { - title - featuredImage { - childImageSharp { - fluid(maxWidth: 800) { - ...GatsbyImageSharpFluid - } - } - } - } - } - } -` -``` - -Your featured image should now appear on the generated page right below the main header. Tada! - -## Inline images with `gatsby-remark-images` - -You may also include images in the Markdown body itself. The plugin [gatsby-remark-images](/plugins/gatsby-remark-images) comes in handy for this. - -Start out by installing `gatsby-remark-images` and `gatsby-plugin-sharp`. - -```shell -npm install gatsby-remark-images gatsby-plugin-sharp -``` - -Also make sure that `gatsby-source-filesystem` is installed and points at the directory where your images are located. - -Configure the plugins in your `gatsby-config` file. As with the previous example, either `Remark` or `MDX` can be used. - -### Using the MDX Plugin - -The below example uses the `gatsby-plugin-mdx` plugin. - -`gatsby-remark-images` needs to be a sub-plugin of `gatsby-plugin-mdx`, included in the `options` field. `gatsby-plugin-sharp` can be included on its own. - -`gatsby-source-filesystem` needs to be pointed at wherever you have your images on disk. - -> Note: This example configuration assumes your images and Markdown pages are sourced from the same directory. Check out the section on [configuring for different directories](#configuring-for-images-and-posts-in-different-directories) for additional help. - -```js:title=gatsby-config.js -module.exports = { - plugins: [ - `gatsby-plugin-sharp`, - { - resolve: `gatsby-plugin-mdx`, - options: { - gatsbyRemarkPlugins: [ - { - resolve: `gatsby-remark-images`, - options: { - maxWidth: 1200, - }, - }, - ], - }, - }, - { - resolve: `gatsby-source-filesystem`, - options: { - path: `${__dirname}/src/pages`, - }, - }, - ], -} -``` - -### Using the Transformer Remark Plugin - -Here is a similar example using the `gatsby-transformer-remark` plugin instead of `gatsby-plugin-mdx`. Put the `gatsby-remark-images` plugin within the `plugins` option field of `gatsby-transformer-remark`. - -```js:title=gatsby-config.js -module.exports = { - plugins: [ - `gatsby-plugin-sharp`, - { - resolve: `gatsby-transformer-remark`, - options: { - plugins: [ - { - resolve: `gatsby-remark-images`, - options: { - maxWidth: 800, - }, - }, - ], - }, - }, - { - resolve: `gatsby-source-filesystem`, - options: { - path: `${__dirname}/src/posts`, - }, - }, - ], -} -``` - -With the configurations above, you can use the default Markdown syntax for images. They will be processed by Sharp and appear as if you placed them in a `gatsby-image` component. - -```markdown -![Hopper The Rabbit](./rabbit-friend.png) -```