{"componentChunkName":"component---src-templates-post-template-js","path":"/2020/02/13/smooth-scroll-toc-gatsby/","result":{"data":{"mdx":{"frontmatter":{"title":"Add a Table of Contents with Smooth scroll using Gatsby and MDX","date":"2020 February 13th"},"body":"function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"date\": \"2020-02-13T00:00:00.000Z\",\n  \"title\": \"Add a Table of Contents with Smooth scroll using Gatsby and MDX\",\n  \"tags\": [\"information\", \"learning\", \"gatsby\", \"guide\", \"mdx\", \"markdown\"],\n  \"published\": true\n};\n\nvar makeShortcode = function makeShortcode(name) {\n  return function MDXDefaultShortcode(props) {\n    console.warn(\"Component \" + name + \" was not imported, exported, or provided by MDXProvider as global scope\");\n    return mdx(\"div\", props);\n  };\n};\n\nvar YouTube = makeShortcode(\"YouTube\");\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"The main purpose for me documenting this is to demonstrate\\nimplementing a table of contents with smooth scroll to the anchors in\\na Gatsby project using MDX.\"), mdx(\"p\", null, \"In the process I\\u2019m also setting up the Gatsby starter with MDX.\"), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"TL;DR, go here:\"), \" \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"#make-a-toc-component\"\n  }), \"Make a TOC component\")), mdx(\"p\", null, \"I like using styled-components for my styling and would like to use\\nthem in this example, so I\\u2019m going to clone the Gatsby starter I made\\nin a \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://thelocalhost.blog/2020/02/06/globally-style-gatsby-styled-components/\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"previous post\"), \".\"), mdx(\"h2\", {\n    \"id\": \"clone-the-gatsby-default-starter-with-styled-components\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#clone-the-gatsby-default-starter-with-styled-components\",\n    \"aria-label\": \"clone the gatsby default starter with styled components permalink\",\n    \"className\": \"anchor before\"\n  }), mdx(\"svg\", _extends({\n    parentName: \"a\"\n  }, {\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }), mdx(\"path\", _extends({\n    parentName: \"svg\"\n  }, {\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), \"Clone the Gatsby Default Starter with styled-components\"), mdx(\"p\", null, \"Spin up a new project using the template I made:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"npx gatsby new \\\\\\n  gatsby-toc-example \\\\\\n  https://github.com/spences10/gatsby-starter-styled-components\\n\")), mdx(\"p\", null, \"Once that has finished installing I\\u2019m going to \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"cd\"), \" into the project\\n(\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"cd gatsby-toc-example\"), \") and install dependencies for using MDX in\\nGatsby.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"# you can use npm if you like\\nyarn add gatsby-plugin-mdx \\\\\\n  @mdx-js/mdx \\\\\\n  @mdx-js/react\\n\")), mdx(\"h2\", {\n    \"id\": \"add-some-content\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#add-some-content\",\n    \"aria-label\": \"add some content permalink\",\n    \"className\": \"anchor before\"\n  }), mdx(\"svg\", _extends({\n    parentName: \"a\"\n  }, {\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }), mdx(\"path\", _extends({\n    parentName: \"svg\"\n  }, {\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), \"Add some content\"), mdx(\"p\", null, \"Create a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"posts\"), \" directory with a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"toc-example\"), \" directory in it which\\ncontains the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"index.mdx\"), \" file I\\u2019ll be adding the content to.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"mkdir -p posts/toc-example\\ntouch posts/toc-example/index.mdx\\n\")), mdx(\"p\", null, \"I\\u2019ll paste in some content, I\\u2019ll take from the \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://raw.githubusercontent.com/spences10/thelocalhost.blog/authoring/posts/2020/02/13/smooth-scroll-toc-gatsby/index.mdx\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"markdown from this\\npost!\")), mdx(\"h2\", {\n    \"id\": \"configure-the-project-to-use-mdx\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#configure-the-project-to-use-mdx\",\n    \"aria-label\": \"configure the project to use mdx permalink\",\n    \"className\": \"anchor before\"\n  }), mdx(\"svg\", _extends({\n    parentName: \"a\"\n  }, {\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }), mdx(\"path\", _extends({\n    parentName: \"svg\"\n  }, {\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), \"Configure the project to use MDX\"), mdx(\"p\", null, \"To enable MDX in the project I\\u2019ll add the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-plugin-mdx\"), \"\\nconfiguration to the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-config.js\"), \" file.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"{\\n  resolve: `gatsby-plugin-mdx`,\\n  options: {\\n    extensions: [`.mdx`, `.md`],\\n    gatsbyRemarkPlugins: [],\\n  },\\n},\\n\")), mdx(\"p\", null, \"I\\u2019ll also need to add the posts directory to the\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-source-filesystem\"), \" config as well.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"{\\n  resolve: `gatsby-source-filesystem`,\\n  options: {\\n    name: `posts`,\\n    path: `${__dirname}/posts`,\\n  },\\n},\\n\")), mdx(\"p\", null, \"Stop the dev server (\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Ctrl+c\"), \" in the terminal) and start with the new\\nconfiguration.\"), mdx(\"p\", null, \"Once the dev server has started back up, I\\u2019ll validate the Gatsby MDX\\nconfig by seeing if \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"allMdx\"), \" is available in the Graph\", mdx(\"em\", null, \"i\"), \"QL\\nexplorer (\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"localhost:8000/___graphql\"), \").\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-graphql\"\n  }), \"{\\n  allMdx {\\n    nodes {\\n      excerpt\\n    }\\n  }\\n}\\n\")), mdx(\"h2\", {\n    \"id\": \"configure-gatsby-node-to-create-the-fields-and-pages\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#configure-gatsby-node-to-create-the-fields-and-pages\",\n    \"aria-label\": \"configure gatsby node to create the fields and pages permalink\",\n    \"className\": \"anchor before\"\n  }), mdx(\"svg\", _extends({\n    parentName: \"a\"\n  }, {\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }), mdx(\"path\", _extends({\n    parentName: \"svg\"\n  }, {\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), \"Configure Gatsby node to create the fields and pages\"), mdx(\"p\", null, \"Here I\\u2019ll make all the paths for the files in the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"posts\"), \" directory,\\ncurrently it\\u2019s only \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-toc-example\"), \". I\\u2019ll do that with\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"createFilePath\"), \" when creating the node fields with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"createNodeField\"), \".\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"const { createFilePath } = require(`gatsby-source-filesystem`)\\n\\nexports.onCreateNode = ({ node, actions, getNode }) => {\\n  const { createNodeField } = actions\\n  if (node.internal.type === `Mdx`) {\\n    const value = createFilePath({ node, getNode })\\n    createNodeField({\\n      name: `slug`,\\n      node,\\n      value,\\n    })\\n  }\\n}\\n\")), mdx(\"p\", null, \"Stop and start the gatsby dev server again as I changed\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-node.js\"), \".\"), mdx(\"p\", null, \"In the Gatsby GraphQL explorer (Graph\", mdx(\"em\", null, \"i\"), \"QL) validate that the\\nfields are being created.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-graphql\"\n  }), \"{\\n  allMdx {\\n    nodes {\\n      fields {\\n        slug\\n      }\\n    }\\n  }\\n}\\n\")), mdx(\"h2\", {\n    \"id\": \"create-a-post-template\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#create-a-post-template\",\n    \"aria-label\": \"create a post template permalink\",\n    \"className\": \"anchor before\"\n  }), mdx(\"svg\", _extends({\n    parentName: \"a\"\n  }, {\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }), mdx(\"path\", _extends({\n    parentName: \"svg\"\n  }, {\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), \"Create a post template\"), mdx(\"p\", null, \"To make the pages for the content in the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"posts\"), \" directory, I\\u2019ll need\\na template to use with the Gatsby \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"createPages\"), \" API.\"), mdx(\"p\", null, \"To do that, I\\u2019ll create a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"templates\"), \" directory in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"src\"), \" then make a\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"post-template.js\"), \" file.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"mkdir src/templates\\ntouch src/templates/post-template.js\\n\")), mdx(\"p\", null, \"For now, I\\u2019m going to return a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"h1\"), \" with \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"Hello template\"), \" so I can\\nvalidate the page was created by Gatsby node.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import React from 'react'\\n\\nexport default () => {\\n  return (\\n    <>\\n      <h1>Hello template</h1>\\n    </>\\n  )\\n}\\n\")), mdx(\"p\", null, \"Save the template, now to create the pages in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-node.js\"), \" I\\u2019m\\nadding the following.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\",\n    \"metastring\": \"{2,4-35}\",\n    \"{2,4-35}\": true\n  }), \"const { createFilePath } = require(`gatsby-source-filesystem`)\\nconst path = require(`path`)\\n\\nexports.createPages = ({ actions, graphql }) => {\\n  const { createPage } = actions\\n  const postTemplate = path.resolve('src/templates/post-template.js')\\n\\n  return graphql(`\\n    {\\n      allMdx(sort: { fields: [frontmatter___date], order: DESC }) {\\n        nodes {\\n          fields {\\n            slug\\n          }\\n        }\\n      }\\n    }\\n  `).then(result => {\\n    if (result.errors) {\\n      throw result.errors\\n    }\\n\\n    const posts = result.data.allMdx.nodes\\n\\n    posts.forEach((post, index) => {\\n      createPage({\\n        path: post.fields.slug,\\n        component: postTemplate,\\n        context: {\\n          slug: post.fields.slug,\\n        },\\n      })\\n    })\\n  })\\n}\\n\\nexports.onCreateNode = ({ node, actions, getNode }) => {\\n  const { createNodeField } = actions\\n  if (node.internal.type === `Mdx`) {\\n    const value = createFilePath({ node, getNode })\\n    createNodeField({\\n      name: `slug`,\\n      node,\\n      value,\\n    })\\n  }\\n}\\n\")), mdx(\"p\", null, \"I know there\\u2019s a lot in there to unpack, so, if you need more detail\\ncheck out the sections in the \\u201D\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://thelocalhost.blog/2019/10/31/build-an-mdx-blog\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"Build a coding blog from scratch with\\nGatsby and MDX\"), \"\\u201D, listed here:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"https://thelocalhost.blog/2019/10/31/build-an-mdx-blog/#index-page-posts-query\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"Index page posts query\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"https://thelocalhost.blog/2019/10/31/build-an-mdx-blog/#slugs-and-paths\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"Slugs and Paths\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"https://thelocalhost.blog/2019/10/31/build-an-mdx-blog/#link-paths\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"Link Paths\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"https://thelocalhost.blog/2019/10/31/build-an-mdx-blog/#adding-a-blog-post-template\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"Adding a Blog Post Template\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"https://thelocalhost.blog/2019/10/31/build-an-mdx-blog/#build-out-blog-post-template\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"Build out Blog Post Template\"))), mdx(\"h2\", {\n    \"id\": \"confirm-the-pages-were-created-with-gatsbys-built-in-404-page\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#confirm-the-pages-were-created-with-gatsbys-built-in-404-page\",\n    \"aria-label\": \"confirm the pages were created with gatsbys built in 404 page permalink\",\n    \"className\": \"anchor before\"\n  }), mdx(\"svg\", _extends({\n    parentName: \"a\"\n  }, {\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }), mdx(\"path\", _extends({\n    parentName: \"svg\"\n  }, {\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), \"Confirm the pages were created with Gatsby\\u2019s built in 404 page\"), mdx(\"p\", null, \"Stop and start the dev server as there\\u2019s been changes to Gatsby node.\"), mdx(\"p\", null, \"Check the page has been created, to do that add \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"/404.js\"), \" to the dev\\nserver url which will show all the available pages in the project.\"), mdx(\"p\", null, \"From here I can select the path created to \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"/toc-example/\"), \" and confirm\\nthe page was created.\"), mdx(\"h2\", {\n    \"id\": \"build-out-the-post-template-to-use-the-mdxrenderer\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#build-out-the-post-template-to-use-the-mdxrenderer\",\n    \"aria-label\": \"build out the post template to use the mdxrenderer permalink\",\n    \"className\": \"anchor before\"\n  }), mdx(\"svg\", _extends({\n    parentName: \"a\"\n  }, {\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }), mdx(\"path\", _extends({\n    parentName: \"svg\"\n  }, {\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), \"Build out the post template to use the MDXRenderer\"), mdx(\"p\", null, \"Now I can add the data to the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"post-template.js\"), \" page from a GraphQL\\nquery. I\\u2019ll do that with the Gatsby \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"graphql\"), \" tag and query some\\nfrontmatter, body and the table of contents.\"), mdx(\"p\", null, \"This query is taking the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"String!\"), \" parameter of \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"slug\"), \" passed to it\\nfrom \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"createPage\"), \" in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-node.js\"), \".\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-graphql\"\n  }), \"query PostBySlug($slug: String!) {\\n  mdx(fields: { slug: { eq: $slug } }) {\\n    frontmatter {\\n      title\\n      date(formatString: \\\"YYYY MMMM Do\\\")\\n    }\\n    body\\n    excerpt\\n    tableOfContents\\n    timeToRead\\n    fields {\\n      slug\\n    }\\n  }\\n}\\n\")), mdx(\"p\", null, \"Destructure the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"body\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"frontmatter\"), \" data from \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"data.mdx\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"data\"), \"\\nis the results of the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"PostBySlug\"), \" query. Wrap the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"body\"), \" data in the\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"<MDXRenderer>\"), \" component.\"), mdx(\"p\", null, \"The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"frontmatter.title\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"frontmatter.date\"), \" can be used in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"h1\"), \" and\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"p\"), \" tags for now.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\",\n    \"metastring\": \"{1-2,5-6,9-10,16-32}\",\n    \"{1-2,5-6,9-10,16-32}\": true\n  }), \"import { graphql } from 'gatsby'\\nimport { MDXRenderer } from 'gatsby-plugin-mdx'\\nimport React from 'react'\\n\\nexport default ({ data }) => {\\n  const { body, frontmatter } = data.mdx\\n  return (\\n    <>\\n      <h1>{frontmatter.title}</h1>\\n      <p>{frontmatter.date}</p>\\n      <MDXRenderer>{body}</MDXRenderer>\\n    </>\\n  )\\n}\\n\\nexport const query = graphql`\\n  query PostBySlug($slug: String!) {\\n    mdx(fields: { slug: { eq: $slug } }) {\\n      frontmatter {\\n        title\\n        date(formatString: \\\"YYYY MMMM Do\\\")\\n      }\\n      body\\n      excerpt\\n      tableOfContents\\n      timeToRead\\n      fields {\\n        slug\\n      }\\n    }\\n  }\\n`\\n\")), mdx(\"p\", null, \"I\\u2019m going to be using \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"tableOfContents\"), \" later when I make a table of\\ncontents component.\"), mdx(\"h2\", {\n    \"id\": \"add-page-elements-for-the-mdxprovider\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#add-page-elements-for-the-mdxprovider\",\n    \"aria-label\": \"add page elements for the mdxprovider permalink\",\n    \"className\": \"anchor before\"\n  }), mdx(\"svg\", _extends({\n    parentName: \"a\"\n  }, {\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }), mdx(\"path\", _extends({\n    parentName: \"svg\"\n  }, {\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), \"Add page elements for the MDXProvider\"), mdx(\"p\", null, \"The content (headings, paragraphs, etc.) were reset with\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"styled-reset\"), \" in the template being used so will need to be added in.\"), mdx(\"p\", null, \"I\\u2019m going to be amending the already existing \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"H1\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"<P>\"), \"\\nstyled-components to be React components so that I can spread in the\\nprops I need for the heading ID.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\",\n    \"metastring\": \"{1,4,11-13}\",\n    \"{1,4,11-13}\": true\n  }), \"import React from 'react'\\nimport styled from 'styled-components'\\n\\nexport const StyledH1 = styled.h1`\\n  font-size: ${({ theme }) => theme.fontSize['4xl']};\\n  font-family: ${({ theme }) => theme.font.serif};\\n  margin-top: ${({ theme }) => theme.spacing[8]};\\n  line-height: ${({ theme }) => theme.lineHeight.none};\\n`\\n\\nexport const H1 = props => {\\n  return <StyledH1 {...props}>{props.children}</StyledH1>\\n}\\n\")), mdx(\"p\", null, \"Create a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"<H2>\"), \" component based off of the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"<H1>\"), \", adjust the spacing\\nand font size.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import React from 'react'\\nimport styled from 'styled-components'\\n\\nexport const StyledH2 = styled.h2`\\n  font-size: ${({ theme }) => theme.fontSize['3xl']};\\n  font-family: ${({ theme }) => theme.font.serif};\\n  margin-top: ${({ theme }) => theme.spacing[6]};\\n  line-height: ${({ theme }) => theme.lineHeight.none};\\n`\\n\\nexport const H2 = props => {\\n  return <StyledH2 {...props}>{props.children}</StyledH2>\\n}\\n\")), mdx(\"p\", null, \"I\\u2019ll need to add the newly created \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"H2\"), \" to the index file for\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"page-elements\"), \":\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\",\n    \"metastring\": \"{2}\",\n    \"{2}\": true\n  }), \"export * from './h1'\\nexport * from './h2'\\nexport * from './p'\\n\")), mdx(\"p\", null, \"Same with the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"<P>\"), \" as I did with the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"H1\"), \", I\\u2019ll switch it to use\\nReact.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import React from 'react'\\nimport styled from 'styled-components'\\n\\nexport const StyledP = styled.p`\\n  margin-top: ${({ theme }) => theme.spacing[3]};\\n  strong {\\n    font-weight: bold;\\n  }\\n  em {\\n    font-style: italic;\\n  }\\n`\\n\\nexport const P = props => {\\n  const { children, ...rest } = props\\n  return <StyledP {...rest}>{children}</StyledP>\\n}\\n\")), mdx(\"p\", null, \"Importing the modified components into the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"root-wrapper.js\"), \" I can now\\npass them into the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"<MDXProvider>\"), \" which is used to map to the HTML\\nelements created in markdown.\"), mdx(\"p\", null, \"There\\u2019s a complete listing of all the HTML elements that can be\\ncustomised on the \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://mdxjs.com/getting-started#table-of-components\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"MDX table of components\"), \".\"), mdx(\"p\", null, \"In this example I\\u2019m mapping the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"H1\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"H2\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"P\"), \" components to the\\ncorresponding HTML elements and passing them into the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"<MDXProvider>\"), \".\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\",\n    \"metastring\": \"{1,5,8-12,17,19}\",\n    \"{1,5,8-12,17,19}\": true\n  }), \"import { MDXProvider } from '@mdx-js/react'\\nimport React from 'react'\\nimport { ThemeProvider } from 'styled-components'\\nimport Layout from './src/components/layout'\\nimport { H1, H2, P } from './src/components/page-elements'\\nimport { GlobalStyle, theme } from './src/theme/global-style'\\n\\nconst components = {\\n  h1: props => <H1 {...props} />,\\n  h2: props => <H2 {...props} />,\\n  p: props => <P {...props} />,\\n}\\n\\nexport const wrapRootElement = ({ element }) => (\\n  <ThemeProvider theme={theme}>\\n    <GlobalStyle />\\n    <MDXProvider components={components}>\\n      <Layout>{element}</Layout>\\n    </MDXProvider>\\n  </ThemeProvider>\\n)\\n\")), mdx(\"h2\", {\n    \"id\": \"add-gatsby-remark-autolink-headers-for-adding-ids-to-headers\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#add-gatsby-remark-autolink-headers-for-adding-ids-to-headers\",\n    \"aria-label\": \"add gatsby remark autolink headers for adding ids to headers permalink\",\n    \"className\": \"anchor before\"\n  }), mdx(\"svg\", _extends({\n    parentName: \"a\"\n  }, {\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }), mdx(\"path\", _extends({\n    parentName: \"svg\"\n  }, {\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), \"Add gatsby-remark-autolink-headers for adding id\\u2019s to headers\"), mdx(\"p\", null, \"Now I have a page, with some content and headers I should now be able\\nto navigate to the individual headings, right?\"), mdx(\"p\", null, \"Well, not quite, although the headers are there, there\\u2019s no IDs in\\nthem to scroll to yet.\"), mdx(\"p\", null, \"I can use \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.gatsbyjs.org/packages/gatsby-remark-autolink-headers/\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"gatsby-remark-autolink-headers\"), \" to create the heading IDs.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"yarn add gatsby-remark-autolink-headers\\n\")), mdx(\"p\", null, \"Add \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-remark-autolink-headers\"), \" in the Gatsby MDX config.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\",\n    \"metastring\": \"{5}\",\n    \"{5}\": true\n  }), \"{\\n  resolve: `gatsby-plugin-mdx`,\\n  options: {\\n    extensions: [`.mdx`, `.md`],\\n    gatsbyRemarkPlugins: [`gatsby-remark-autolink-headers`],\\n  },\\n},\\n\")), mdx(\"p\", null, \"As I\\u2019ve changed the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-config.js\"), \" file I\\u2019ll need to stop and\\nstart the dev server.\"), mdx(\"p\", null, \"Fix the weird positioning on the SVGs for the links added by\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-remark-autolink-headers\"), \".\"), mdx(\"p\", null, \"Do that by making some reusable CSS with a tagged template literal,\\nI\\u2019ll put it in it\\u2019s own file \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"heading-link.js\"), \".\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"touch src/components/page-elements/heading-link.js\\n\")), mdx(\"p\", null, \"Then add the CSS in as a template literal:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"export const AutoLink = `\\n  a {\\n    float: left;\\n    padding-right: 4px;\\n    margin-left: -20px;\\n  }\\n  svg {\\n    visibility: hidden;\\n  }\\n  &:hover {\\n    a {\\n      svg {\\n        visibility: visible;\\n      }\\n    }\\n  }\\n`\\n\")), mdx(\"p\", null, \"Then I\\u2019m going to use that (\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"AutoLink\"), \") in the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"H2\"), \" and anywhere else\\nthat could have a link applied to it (any heading element).\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\",\n    \"metastring\": \"{10}\",\n    \"{10}\": true\n  }), \"import React from 'react'\\nimport styled from 'styled-components'\\nimport { AutoLink } from './linked-headers'\\n\\nexport const StyledH2 = styled.h2`\\n  font-size: ${({ theme }) => theme.fontSize['3xl']};\\n  font-family: ${({ theme }) => theme.font.serif};\\n  margin-top: ${({ theme }) => theme.spacing[6]};\\n  line-height: ${({ theme }) => theme.lineHeight.none};\\n  ${AutoLink}\\n`\\n\\nexport const H2 = props => {\\n  return <StyledH2 {...props}>{props.children}</StyledH2>\\n}\\n\")), mdx(\"p\", null, \"Clicking around on the links now should scroll to each one smoothly\\nand have the SVG for the link only visible on hover.\"), mdx(\"h2\", {\n    \"id\": \"make-a-toc-component\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#make-a-toc-component\",\n    \"aria-label\": \"make a toc component permalink\",\n    \"className\": \"anchor before\"\n  }), mdx(\"svg\", _extends({\n    parentName: \"a\"\n  }, {\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }), mdx(\"path\", _extends({\n    parentName: \"svg\"\n  }, {\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), \"Make a TOC component\"), mdx(\"p\", null, \"From here onwards is what the whole post boils down to! I did want to\\ngo through the process of how you would do something similar yourself\\nthough, so I\\u2019m hoping this has helped in some way.\"), mdx(\"p\", null, \"For the TOC with smooth scroll you need several things:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"scroll-behavior: smooth;\"), \" added to your \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"html\"), \", this is part of the\\nstarter I made in a \", mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"https://thelocalhost.blog/2020/02/06/globally-style-gatsby-styled-components/\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"previous post\"), \".\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"IDs in the headings to scroll to, this is done with\\n\", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"gatsby-remark-autolink-headers\"), \".\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"A table of contents which is provided by Gatsby MDX with\\n\", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"tableOfContents\"), \".\")), mdx(\"p\", null, \"The first two parts have been covered so now to create a TOC\\ncomponent, with styled-components.\"), mdx(\"p\", null, \"In the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"post-template.js\"), \" I\\u2019ll create a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Toc\"), \" component for some\\npositioning and create a scrollable div to use inside of that.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"const Toc = styled.ul`\\n  position: fixed;\\n  left: calc(50% + 400px);\\n  top: 110px;\\n  max-height: 70vh;\\n  width: 310px;\\n  display: flex;\\n  li {\\n    line-height: ${({ theme }) => theme.lineHeight.tight};\\n    margin-top: ${({ theme }) => theme.spacing[3]};\\n  }\\n`\\n\\nconst InnerScroll = styled.div`\\n  overflow: hidden;\\n  overflow-y: scroll;\\n`\\n\")), mdx(\"p\", null, \"The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"main\"), \" content is overlapping with the TOC here so I\\u2019m going to\\nadd a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"maxWidth\"), \" inline on the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"layout.js\"), \" component.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"<main style={{ maxWidth: '640px' }}>{children}</main>\\n\")), mdx(\"h2\", {\n    \"id\": \"conditionally-render-the-toc\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#conditionally-render-the-toc\",\n    \"aria-label\": \"conditionally render the toc permalink\",\n    \"className\": \"anchor before\"\n  }), mdx(\"svg\", _extends({\n    parentName: \"a\"\n  }, {\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }), mdx(\"path\", _extends({\n    parentName: \"svg\"\n  }, {\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), \"Conditionally render the TOC\"), mdx(\"p\", null, \"Time to map over the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"tableOfContents\"), \" object:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"{\\n  typeof tableOfContents.items === 'undefined' ? null : (\\n    <Toc>\\n      <InnerScroll>\\n        <H2>Table of contents</H2>\\n        {tableOfContents.items.map(i => (\\n          <li key={i.url}>\\n            <a href={i.url} key={i.url}>\\n              {i.title}\\n            </a>\\n          </li>\\n        ))}\\n      </InnerScroll>\\n    </Toc>\\n  )\\n}\\n\")), mdx(\"p\", null, \"Here\\u2019s the full \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"post-template.js\"), \" file, I\\u2019ve reused the\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"page-elements\"), \" components for the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"h1\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"h2\"), \" on the TOC and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"p\"), \":\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\",\n    \"metastring\": \"{4-5,7-18,20-23,26,29-44}\",\n    \"{4-5,7-18,20-23,26,29-44}\": true\n  }), \"import { graphql } from 'gatsby'\\nimport { MDXRenderer } from 'gatsby-plugin-mdx'\\nimport React from 'react'\\nimport styled from 'styled-components'\\nimport { H1, H2, P } from '../components/page-elements'\\n\\nconst Toc = styled.ul`\\n  position: fixed;\\n  left: calc(50% + 400px);\\n  top: 110px;\\n  max-height: 70vh;\\n  width: 310px;\\n  display: flex;\\n  li {\\n    line-height: ${({ theme }) => theme.lineHeight.tight};\\n    margin-top: ${({ theme }) => theme.spacing[3]};\\n  }\\n`\\n\\nconst InnerScroll = styled.div`\\n  overflow: hidden;\\n  overflow-y: scroll;\\n`\\n\\nexport default ({ data }) => {\\n  const { body, frontmatter, tableOfContents } = data.mdx\\n  return (\\n    <>\\n      <H1>{frontmatter.title}</H1>\\n      <P>{frontmatter.date}</P>\\n      {typeof tableOfContents.items === 'undefined' ? null : (\\n        <Toc>\\n          <InnerScroll>\\n            <H2>Table of contents</H2>\\n            {tableOfContents.items.map(i => (\\n              <li key={i.url}>\\n                <a href={i.url} key={i.url}>\\n                  {i.title}\\n                </a>\\n              </li>\\n            ))}\\n          </InnerScroll>\\n        </Toc>\\n      )}\\n      <MDXRenderer>{body}</MDXRenderer>\\n    </>\\n  )\\n}\\n\\nexport const query = graphql`\\n  query PostBySlug($slug: String!) {\\n    mdx(fields: { slug: { eq: $slug } }) {\\n      frontmatter {\\n        title\\n        date(formatString: \\\"YYYY MMMM Do\\\")\\n      }\\n      body\\n      excerpt\\n      tableOfContents\\n      timeToRead\\n      fields {\\n        slug\\n      }\\n    }\\n  }\\n`\\n\")), mdx(\"p\", null, \"That\\u2019s it, I can play around navigating between headings now from the\\nTOC.\"), mdx(\"h2\", {\n    \"id\": \"-heres-a-video-detailing-the-process\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#-heres-a-video-detailing-the-process\",\n    \"aria-label\": \" heres a video detailing the process permalink\",\n    \"className\": \"anchor before\"\n  }), mdx(\"svg\", _extends({\n    parentName: \"a\"\n  }, {\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }), mdx(\"path\", _extends({\n    parentName: \"svg\"\n  }, {\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), \"\\uD83D\\uDCFA Here\\u2019s a video detailing the process.\"), mdx(YouTube, {\n    youTubeId: \"Kp51KajhluE\",\n    mdxType: \"YouTube\"\n  }), mdx(\"h2\", {\n    \"id\": \"resources-that-helped-me\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#resources-that-helped-me\",\n    \"aria-label\": \"resources that helped me permalink\",\n    \"className\": \"anchor before\"\n  }), mdx(\"svg\", _extends({\n    parentName: \"a\"\n  }, {\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }), mdx(\"path\", _extends({\n    parentName: \"svg\"\n  }, {\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), \"Resources that helped me\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"https://johno.com/mdx-table-of-contents-components-in-gatsby\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"4pine\\u2019s blog\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"https://theme-ui.com/guides/linked-headings/\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"Theme UI guide\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"https://github.com/ChristopherBiscardi/gatsby-mdx/issues/396\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"Gatsby MDX repo issue 396\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"https://github.com/ChristopherBiscardi/gatsby-mdx/issues/140\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"Gatsby MDX repo issue 140\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"https://github.com/ChristopherBiscardi/gatsby-mdx/issues/204\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"Gatsby MDX repo issue 204\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"https://github.com/mdx-js/mdx/issues/810\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"MDX JS repo issue 810\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"https://github.com/remarkjs/remark-slug\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"remark-slug repo\"))), mdx(\"h2\", {\n    \"id\": \"thanks-for-reading-\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#thanks-for-reading-\",\n    \"aria-label\": \"thanks for reading  permalink\",\n    \"className\": \"anchor before\"\n  }), mdx(\"svg\", _extends({\n    parentName: \"a\"\n  }, {\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }), mdx(\"path\", _extends({\n    parentName: \"svg\"\n  }, {\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), \"Thanks for reading \\uD83D\\uDE4F\"), mdx(\"p\", null, \"Please take a look at my other content if you enjoyed this.\"), mdx(\"p\", null, \"Follow me on \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://twitter.com/spences10\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"Twitter\"), \" or \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/spences10/ama\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"Ask Me Anything\"), \" on GitHub.\"), mdx(\"hr\", null));\n}\n;\nMDXContent.isMDXComponent = true;","excerpt":"The main purpose for me documenting this is to demonstrate\nimplementing a table of contents with smooth scroll to the anchors in\na Gatsby…","tableOfContents":{"items":[{"url":"#clone-the-gatsby-default-starter-with-styled-components","title":"Clone the Gatsby Default Starter with styled-components"},{"url":"#add-some-content","title":"Add some content"},{"url":"#configure-the-project-to-use-mdx","title":"Configure the project to use MDX"},{"url":"#configure-gatsby-node-to-create-the-fields-and-pages","title":"Configure Gatsby node to create the fields and pages"},{"url":"#create-a-post-template","title":"Create a post template"},{"url":"#confirm-the-pages-were-created-with-gatsbys-built-in-404-page","title":"Confirm the pages were created with Gatsby's built in 404 page"},{"url":"#build-out-the-post-template-to-use-the-mdxrenderer","title":"Build out the post template to use the MDXRenderer"},{"url":"#add-page-elements-for-the-mdxprovider","title":"Add page elements for the MDXProvider"},{"url":"#add-gatsby-remark-autolink-headers-for-adding-ids-to-headers","title":"Add gatsby-remark-autolink-headers for adding id's to headers"},{"url":"#make-a-toc-component","title":"Make a TOC component"},{"url":"#conditionally-render-the-toc","title":"Conditionally render the TOC"},{"url":"#-heres-a-video-detailing-the-process","title":"📺 Here's a video detailing the process."},{"url":"#resources-that-helped-me","title":"Resources that helped me"},{"url":"#thanks-for-reading-","title":"Thanks for reading 🙏"}]},"timeToRead":4,"fields":{"slug":"/2020/02/13/smooth-scroll-toc-gatsby/","editLink":"https://github.com/spences10/thelocalhost/edit/authoring/posts/2020/02/13/smooth-scroll-toc-gatsby/index.mdx"}}},"pageContext":{"slug":"/2020/02/13/smooth-scroll-toc-gatsby/","previous":{"id":"88c8a4da-3fd4-5e17-9f0d-bc3356165784","excerpt":"I'm going to go over globally styling the Gatsby Default Starter with\nstyled-components v5, I've done this in the  past with\nstyled-components v4  but I've changed my approach and want to\ndocument it. I'll be swapping out the styles included with a…","frontmatter":{"title":"Globally Style the Gatsby Default Starter with styled-components v5","date":"2020-02-06T00:00:00.000Z"},"fields":{"slug":"/2020/02/06/globally-style-gatsby-styled-components/"}},"next":{"id":"d121f762-9302-559b-9005-9333c2f6b4b4","excerpt":"Fathom Analytics recently added a really neat feature for  custom\ndomains  with their service. What does that mean then? Well it's for bypassing ad-blocking\nextensions, not that Fathom wants to collect all your data,  far from\nit . The purpose of…","frontmatter":{"title":"Create a Custom Domain for Fathom Analytics","date":"2020-04-16T00:00:00.000Z"},"fields":{"slug":"/2020/04/16/fathom-create-custom-domain/"}}}}}