{"componentChunkName":"component---src-templates-blog-post-template-js","path":"/2019/10/31/build-an-mdx-blog/","result":{"data":{"mdx":{"id":"5cebc425-55bf-5894-b964-37054823e574","frontmatter":{"title":"Build a coding blog from scratch with Gatsby and MDX","date":"2019 October 31st","cover":{"id":"ec84d26b-cd40-548b-9061-998a5a80e20d","publicURL":"/static/cover-774c894b6a10a40e4454da235fa0ae40.jpg"}},"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\": \"2019-10-31T00:00:00.000Z\",\n  \"title\": \"Build a coding blog from scratch with Gatsby and MDX\",\n  \"tags\": [\"information\", \"learning\", \"gatsby\", \"guide\", \"mdx\", \"markdown\"],\n  \"published\": true,\n  \"cover\": \"./cover.jpg\",\n  \"coverCredit\": \"Photo by SpaceX on Unsplash\"\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, \"I have been a Gatsby user since around \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/spences10/blog.scottspence.me/tree/a470e8563e1a040527cf2094fc1b377550a88c77\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"v0 May 2017\"), \", at that time was\\nusing a template called \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/alxshelepenok/gatsby-starter-lumen\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"Lumen\"), \" and it was just what I needed at the\\ntime. Since then I have have gone from using a template to creating my\\nblog.\"), mdx(\"p\", null, \"Over the years I have made my own \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://lengstorf.com/progressive-disclosure-of-complexity/\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"Progressive Disclosure of\\nComplexity\"), \" with Gatsby to where I am now.\"), mdx(\"h2\", {\n    \"id\": \"what-does-that-mean\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#what-does-that-mean\",\n    \"aria-label\": \"what does that mean permalink\",\n    \"className\": \"anchor-toc 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  })))), \"What does that mean?\"), mdx(\"p\", null, \"It means that although there are an awesome amount of Gatsby starters\\nand themes out there to get you up and running in minutes, this post\\nis going to focus on what you need to do to build your own blog.\\nStarting with the most basic \\u201CHello World!\\u201D to deploying your code to\\nproduction.\"), mdx(\"h2\", {\n    \"id\": \"what-youre-going-to-build\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#what-youre-going-to-build\",\n    \"aria-label\": \"what youre going to build permalink\",\n    \"className\": \"anchor-toc 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  })))), \"What you\\u2019re going to build\"), mdx(\"p\", null, \"You\\u2019re going to build a developer blog with MDX support (for some\\nReact components in Markdown goodness), so you will be able to add\\nyour own React components into your Markdown posts.\"), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"There\\u2019ll be:\")), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Adding a Layout\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Basic styling with styled-components\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Code blocks with syntax highlighting\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Copy code snippet to clipboard\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Cover images for the posts\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Configuring an SEO component\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Deploying it to Netlify\")), mdx(\"h2\", {\n    \"id\": \"whos-this-how-to-for\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#whos-this-how-to-for\",\n    \"aria-label\": \"whos this how to for permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Who\\u2019s this how-to for?\"), mdx(\"p\", null, \"People that may have used Gatsby before as a template and now want to\\nget more involved in how to make changes.\"), mdx(\"p\", null, \"If you want to have code syntax highlighting.\"), mdx(\"p\", null, \"If you want to use styled-components in an app.\"), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"I really want to avoid this!\")), mdx(\"p\", null, mdx(\"span\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"640px\"\n    }\n  }), \"\\n      \", mdx(\"a\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/c94426ee247944669175d7575b851f60/dba9a/draw-a-horse-quincy-tweet.png\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": [\"noopener\"]\n  }), \"\\n    \", mdx(\"span\", _extends({\n    parentName: \"a\"\n  }, {\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"132.82208588957053%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/svg+xml,%3csvg%20xmlns=\\\\'http://www.w3.org/2000/svg\\\\'%20width=\\\\'400\\\\'%20height=\\\\'531\\\\'%3e%3cpath%20d=\\\\'M0%20266c0%20264%200%20265%202%20265s2-1%202-263L5%205c2-2%20388-1%20390%200l1%20264v262h5V0H0v266M38%2026l-1%209c0%207%200%207-3%209l-3%203%202%202c5%205%209%204%208-1l1-2c1%201%202%200%204-1s3-1%201%204c-1%202%203%202%205%200%203-2%202-2-1-4-3-1-3-1-2-3v-5c-1%202-1%202-3%200-3-2-2-3%201-2%202%200%203%200%203-2s0-2-4-2c-5%201-7-5-2-6%202-1%202-1-1-1l-5%202m112%2072c-1%202-1%202-3%200-2-1-2-1-4%201l-1%202-2-2c-3-4-4-1-2%204%203%204%207%206%207%203s2-2%203%200c3%203%205%202%205-3%201-7-1-9-3-5m-84%2024c0%2013%200%2013%203%2013%204%200%209-7%209-11%200-3-3-7-8-10-5-4-5-3-4%208m39-9l6%2019c2%205%208%203%207-3-1-3%200-2%202%203%203%205%204%207%206%207%201%200%202-1%202-13l-1-12c-2-1-2%200-3%207-1%206-2%206-4%200s-5-10-6-8l-1%206v6l-2-6c-2-6-6-10-6-6m-25%2011c0%2010%202%2014%204%2013v-11l3%204%205%204c2%200%201-4%200-5-3-1-5-5-4-6%203-4%200-9-6-9h-3l1%2010m15%200l1%2011c2%202%203%200%203-3%200-4%202-4%204%201%202%203%205%204%205%202%200-5-9-21-11-21l-2%2010m73-4c0%206-1%207-3%201l-3-5c-2%200-1%2019%201%2022s4%202%204-3c0-6%201-7%202%200%200%205%202%208%204%206%201-1%200-23-2-24-2-3-3-2-3%203m18-4v7l2%209c1%207%205%207%204%201l-1-4%204%204%205%204c2%200%203-2%201-3l-4-4c-3-3-3-3-2-5%203-2%202-5-1-8-2-2-7-3-8-1m16%201c-3%204-3%205%202%209s5%206%201%206-4%202%200%203c4%202%207%200%207-4%200-2-3-5-7-8-1-1-1-1%201-3%203-3%203-5%200-5l-4%202m12-1v22c1%201%2014%200%2014-2%200-1-2-2-7-2-4%200-4%200-4-3s1-4%204-4c6-2%205-5-1-4-3%200-3%200-3-2%200-1%201-2%203-2%204-1%203-3-2-4l-4%201m-71%202c-2%203-1%2020%201%2020l2-4c0-4%201-4%203%200%201%203%205%204%204%201-4-17-7-22-10-17m33%200c-2%202-1%2014%201%2016%205%206%2010%202%209-7-1-8-6-13-10-9m15%2065l-1%205-1%201c0%201%201%201%202-1l2-2%201%204c2%204%202%204%200%204l-4-2c-1-2-2-2-3%200v1c3-1%205%202%202%204s-4%206-1%2012c2%205%202%203%200-2v-6c1-3%207-7%209-6h1l2-1h2l7%201%205-1-9-1h-8l-2-5-2-5-1-2c-1-1-1%200-1%202m32%2021c1%2010-4%2014-18%2013a39%2039%200%2001-13-3l3%2022%201-3-2-10c0-9%201-6%203%204%200%206%202%2010%202%207l-1-10v-7c1%200%202%201%203%2011l2%205-1-8v-7l2%208%202%209c1%201%201%201%201-1l-2-9c0-7%200-7%202-6%202%200%202%201%204%209%201%207%203%2010%202%203-2-11-2-13-1-13l1%202%203%2015%201-2c-2-4-3-14-2-15%202-2%203-1%205%207l2%207%201-2c-3-6-4-13-3-14s2%201%203%207c0%205%201%209%202%209l-1-5v-21l-1-6v4m-52%2074l-3%205c-2%203-2%204%201%202s10-1%2011%201c1%204%201%206-1%208-2%203-2%203%200%205s2%202-1%205-4%205-2%2010c2%202%202%202%201-2%200-5%200-6%202-7l3-2%202-1h2l3-1h4c2-1%2012%200%2016%203h2c-1-2-9-5-15-5l-6-1c1-1-1-5-5-12l-3-3-3-2c0-2-1-3-3-2l-4-1h-1m52%2021l-8%204c-5%203-5%203-3%206%202%204%200%2010-4%2012-7%204-21%203-27-2-1-2-3-3-3-2l2%202c2%202%203%2012%203%2022%201%203%202%203%204%202s2-2%200-10v-9c2%200%204%2010%204%2016%200%202%201%203%202%203%203%201%204-1%203-4l-2-9c0-5%200-5%202-5%203%200%203%201%204%208l1%209c0%201%204%202%205%200v-3l-2-9c0-6%200-6%202-6l5%2016c-1%201%203%203%204%202l-1-12c-1-7-2-11-1-13l1-5c0-3%201-4%205-6%205-3%205-3%207%201%201%202%201%203%203%202h3c2%202%200-4-2-8-3-3-2-3-7-2m-100%206c3%204%203%2011%200%2015-3%203-12%204-19%203l-7-1%201%208v9l-1-9c0-8-1-9-3-11-3-2-4-2-2%201%202%201%202%205%203%2013%201%2012%202%2012%204%2010s2-2%201-8l-1-10c0-5%203%201%204%2010%201%208%201%208%204%208%202%200%202%200%202-3l-2-9c-1-6-1-6%202-6%202%200%204%206%204%2014%200%204%201%204%203%204%203%200%203%200%203-3l-3-15%202-1c2%200%205%2010%205%2015%200%202%203%204%204%202l-1-11-1-11c3-4%200-17-4-17l2%203m-21%2083c0%202-1%202-3%201-2%200-3%200-4%202s-3%202-7-2h-2v1c-2-1-1%202%201%203l2%201%201%201%201%202c2%202%202%202%202%200l-1-3v-1l2%204c2%204%209%206%209%202%201-2%201-2%201%200%201%202%201%204-1%207l-2%2012c-1%209-3%2012-6%207-2-3-3-1%200%203%201%202%202%203%204%203%203%200%204-2%204-8%200-4-1-4%207%204%202%203%203%204%205%203h3l-2-3c-4-4-7-13-7-18%200-7%202-7%202%200v6l2-6c2-5%203-6%203-1l1%207%201%205%202-3c0-2%201-2%201-1l1%202%201%202c0%204%202%202%202-2%201-3%201-2%201%202l1%206c1%200%204-11%204-16%200-6%202-6%209-2%205%202%205%203%204%201s-8-6-10-6c-5%200-5%200-5%205v5l-2-3-1-3-1%202-1%201-1-1c-2%201-2%200-2-1%200-3-2-3-2%200s0%203-1%200l-2-7c-2-3-2-3-2-1-1%202-1%202-5-1-3-3-4-7-1-7l-1-1-2-2c-1-2-3-2-3-1m162%2078c-5%202-7%208-3%2012%205%205%2012%201%2012-5%200-5-5-9-9-7m-71%201v3c0%201%200%202-2%203-3%200-3%203%200%206%202%202%203%201%203-1l1-2v2l1%202c2%200%204-1%204-4l1-2v-5l-2-3-1%203-1%204v-4c0-3-2-4-4-2m16%201l-1%202-1%201v7l1-1%202-1c1%200%202%200%201%201h-1l-1%201c1%203%206%202%209%200%203-3%203-5%200-5h-2l2-1c2%200%201-4-2-5s-5-1-7%201m87%201c-4%205-2%2010%205%2010%204%200%204%200%205-3l2-2v-5c-1-2-2-2-4-1l-4%201%201-1a303%20303%200%20001-2c-3%200-4%201-6%203m-138-1l-2%203h-1c-2-2-3-1-3%202%200%201%201%203%203%203l2%202c0%202%204%203%205%201%201-1%202-2%201-3l2-1%202-1-2-1-2-2c0-3-3-4-5-3m73%201l-5%201c-2%200-3%202-2%205%201%202%202%203%203%202%201%200%203%200%203%202h4c4-3%204-9%201-11-2-1-2-1-4%201\\\\'%20fill=\\\\'%23d3d3d3\\\\'%20fill-rule=\\\\'evenodd\\\\'/%3e%3c/svg%3e')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  })), \"\\n  \", mdx(\"picture\", {\n    parentName: \"a\"\n  }, \"\\n        \", mdx(\"source\", _extends({\n    parentName: \"picture\"\n  }, {\n    \"srcSet\": [\"/static/c94426ee247944669175d7575b851f60/60a22/draw-a-horse-quincy-tweet.webp 160w\", \"/static/c94426ee247944669175d7575b851f60/4c812/draw-a-horse-quincy-tweet.webp 320w\", \"/static/c94426ee247944669175d7575b851f60/0ba47/draw-a-horse-quincy-tweet.webp 640w\", \"/static/c94426ee247944669175d7575b851f60/db2ac/draw-a-horse-quincy-tweet.webp 652w\"],\n    \"sizes\": \"(max-width: 640px) 100vw, 640px\",\n    \"type\": \"image/webp\"\n  })), \"\\n        \", mdx(\"source\", _extends({\n    parentName: \"picture\"\n  }, {\n    \"srcSet\": [\"/static/c94426ee247944669175d7575b851f60/69538/draw-a-horse-quincy-tweet.png 160w\", \"/static/c94426ee247944669175d7575b851f60/72799/draw-a-horse-quincy-tweet.png 320w\", \"/static/c94426ee247944669175d7575b851f60/6af66/draw-a-horse-quincy-tweet.png 640w\", \"/static/c94426ee247944669175d7575b851f60/dba9a/draw-a-horse-quincy-tweet.png 652w\"],\n    \"sizes\": \"(max-width: 640px) 100vw, 640px\",\n    \"type\": \"image/png\"\n  })), \"\\n        \", mdx(\"img\", _extends({\n    parentName: \"picture\"\n  }, {\n    \"className\": \"gatsby-resp-image-image\",\n    \"src\": \"/static/c94426ee247944669175d7575b851f60/6af66/draw-a-horse-quincy-tweet.png\",\n    \"alt\": \"draw a horse quincy tweet\",\n    \"title\": \"draw a horse quincy tweet\",\n    \"loading\": \"lazy\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    }\n  })), \"\\n      \"), \"\\n  \"), \"\\n    \")), mdx(\"p\", null, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://twitter.com/ossia/status/588389121053200385\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"draw a horse Quincy tweet\")), mdx(\"h2\", {\n    \"id\": \"requirements\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#requirements\",\n    \"aria-label\": \"requirements permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Requirements\"), mdx(\"p\", null, \"You\\u2019re going to need a basic web development setup: node, terminal\\n(bash, zsh or fish) and a text editor.\"), mdx(\"p\", null, \"I do like to use \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://codesandbox.io\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"codesandbox.io\"), \" for these sort of guides to reduce\\nthe barrier to entry but in this case I have found there are some\\nlimitations with starting out from scratch on \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://codesandbox.io\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"codesandbox.io\"), \" which\\ndoesn\\u2019t make this possible.\"), mdx(\"p\", null, \"I have made a guide on getting set up for web development with\\n\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"http://blog.scottspence.me/wsl-bootstrap-2019\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"Windows Web-Dev Bootstrap\"), \" and covered the same process in \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.youtube.com/watch?v=eSAsdQuQ-1o\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"Ubuntu as\\nwell\"), \".\"), mdx(\"p\", null, \"Ok? Time to get started!\"), mdx(\"h2\", {\n    \"id\": \"hello-world\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#hello-world\",\n    \"aria-label\": \"hello world permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Hello World\"), mdx(\"p\", null, \"Kick this off with the Gatsby \\u2018hello world\\u2019, you\\u2019ll need to initialise\\nthe project with:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"npm init -y\\ngit init\\n\")), mdx(\"p\", null, \"I suggest that you commit this code to a git repository, so you should\\nstart with a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".gitignore\"), \" file.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"touch .gitignore\\n\\necho \\\"# Project dependencies\\n.cache\\nnode_modules\\n\\n# Build directory\\npublic\\n\\n# Other\\n.DS_Store\\nyarn-error.log\\\" > .gitignore\\n\")), mdx(\"p\", null, \"Ok now is a good time to do a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"git init\"), \" and if you\\u2019re using VSCode\\nyou\\u2019ll see the changes reflected in the sidebar.\"), mdx(\"h3\", {\n    \"id\": \"basic-hello-world\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h3\"\n  }, {\n    \"href\": \"#basic-hello-world\",\n    \"aria-label\": \"basic hello world permalink\",\n    \"className\": \"anchor-toc 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  })))), \"basic hello world\"), mdx(\"p\", null, \"Ok a Gatsby hello world, get started with the bare minimum! Install\\nthe following:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"yarn add gatsby react react-dom\\n\")), mdx(\"p\", null, \"You\\u2019re going to need to create a pages directory and add an index\\nfile. You can do that in the terminal by typing the following:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"# -p is to create parent directories too if needed\\nmkdir -p src/pages\\ntouch src/pages/index.js\\n\")), mdx(\"p\", null, \"Ok, now you can commence the hello word incantation! In the newly\\ncreated \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"index.js\"), \" enter the following:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import React from 'react';\\n\\nexport default () => {\\n  return <h1>Hello World!</h1>;\\n};\\n\")), mdx(\"p\", null, \"Now you need to add the Gatsby develop script to the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"package.json\"), \"\\nfile, \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"-p\"), \" specifies what port you want to run the project on and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"-o\"), \"\\nopens a new tab on your default browser, so in this case\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"localhost:9988\"), \":\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-json\"\n  }), \"\\\"dev\\\": \\\"gatsby develop -p 9988 -o\\\"\\n\")), mdx(\"p\", null, \"Ok it\\u2019s time to run the code! From the terminal type the npm script\\ncommand you just created:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"yarn dev\\n\")), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"Note I\\u2019m using Yarn for installing all my dependencies and running\\nscripts, if you prefer you can use npm just bear in mind that the\\ncontent on here uses yarn, so swap out commands where needed\")), mdx(\"p\", null, \"And with that the \\u201CHello World\\u201D incantation is complete \\uD83E\\uDDD9!\"), mdx(YouTube, {\n    youTubeId: \"2vP3ZTDbN1g\",\n    mdxType: \"YouTube\"\n  }), mdx(\"h2\", {\n    \"id\": \"add-content\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#add-content\",\n    \"aria-label\": \"add content permalink\",\n    \"className\": \"anchor-toc 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 content\"), mdx(\"p\", null, \"Ok, now you have the base your blog you\\u2019re going to want to add some\\ncontent, first up we\\u2019re going to get the convention out of the way.\\nFor this how-to, the date format will be a logical way, the most\\nlogical way for a date format is \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"YYYYMMDD\"), \", fight me!\"), mdx(\"p\", null, \"So you\\u2019re going to structure your posts content in years, in each one\\nof those you\\u2019re going to have another folder relating to the post with\\nthe (correct) date format for the beginning of the file followed by\\nthe title of the post. You could drill into this further if you like\\nby separating out months and days depending on the volume of posts\\ngoing this may be a good approach. In this case and in the examples\\nprovided the convention detailed will be used.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"# create multiple directories using curly braces\\nmkdir -p posts/2019/{2019-06-01-hello-world,2019-06-10-second-post,2019-06-20-third-post}\\ntouch posts/2019/2019-06-01-hello-world/index.mdx\\ntouch posts/2019/2019-06-10-second-post/index.mdx\\ntouch posts/2019/2019-06-20-third-post/index.mdx\\n\")), mdx(\"p\", null, \"Ok that\\u2019s your posts set up now you need to add some content to them,\\neach file you have in here should have frontmatter. Frontmatter is a\\nway to assign properties to the contents, in this case a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"title\"), \",\\npublished \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"date\"), \" and a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"published\"), \" flag (\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"true\"), \" or \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"false\"), \").\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-md\"\n  }), \"---\\ntitle: Hello World - from mdx!\\ndate: 2019-06-01\\npublished: true\\n---\\n\\n# h1 Heading\\n\\nMy first post!!\\n\\n## h2 Heading\\n\\n### h3 Heading\\n\")), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-md\"\n  }), \"---\\ntitle: Second Post!\\ndate: 2019-06-10\\npublished: true\\n---\\n\\nThis is my second post!\\n\\n#### h4 Heading\\n\\n##### h5 Heading\\n\\n###### h6 Heading\\n\")), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-md\"\n  }), \"---\\ntitle: Third Post!\\ndate: 2019-06-20\\npublished: true\\n---\\n\\nThis is my third post!\\n\\n> with a block quote!\\n\")), mdx(\"h2\", {\n    \"id\": \"gatsby-config-api\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#gatsby-config-api\",\n    \"aria-label\": \"gatsby config api permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Gatsby config API\"), mdx(\"p\", null, \"Ok, now you\\u2019re going to configure Gatsby so that it can read your\\nsuper awesome content you just created. So, first up you need to\\ncreate a the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-config.js\"), \" file, in the terminal create the file:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"touch gatsby-config.js\\n\")), mdx(\"h2\", {\n    \"id\": \"plugins\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#plugins\",\n    \"aria-label\": \"plugins permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Plugins\"), mdx(\"p\", null, \"And now you can add the plugins Gatsby needs to use for sourcing and\\ndisplaying the the files you just created.\"), mdx(\"h3\", {\n    \"id\": \"gatsby-source-filesystem\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h3\"\n  }, {\n    \"href\": \"#gatsby-source-filesystem\",\n    \"aria-label\": \"gatsby source filesystem permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Gatsby source filesystem\"), mdx(\"p\", null, \"The \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.gatsbyjs.org/packages/gatsby-source-filesystem/\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"gatsby-source-filesystem\"), \" collects the files on the local\\nfilesystem for use in Gatsby once configured.\"), mdx(\"h3\", {\n    \"id\": \"gatsby-plugin-mdx\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h3\"\n  }, {\n    \"href\": \"#gatsby-plugin-mdx\",\n    \"aria-label\": \"gatsby plugin mdx permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Gatsby plugin MDX\"), mdx(\"p\", null, \"The \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.gatsbyjs.org/packages/gatsby-plugin-mdx/\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"gatsby-plugin-mdx\"), \" is what will be allowing us to write JSX in\\nour Markdown documents and the heart of how the content is displayed\\nin the blog.\"), mdx(\"p\", null, \"Now is a good time to also add in dependent packages for the Gatsby\\nplugin MDX which are \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"@mdx-js/mdx\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"@mdx-js/react\"), \".\"), mdx(\"p\", null, \"In the terminal install the dependencies:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"yarn add gatsby-plugin-mdx @mdx-js/mdx @mdx-js/react gatsby-source-filesystem\\n\")), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"touch gatsby-config.js\\n\")), mdx(\"p\", null, \"Now its time to configure \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-config.js\"), \":\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"module.exports = {\\n  siteMetadata: {\\n    title: `The Localhost Blog`,\\n    description: `This is my coding blog where I write about my coding journey.`,\\n  },\\n  plugins: [\\n    {\\n      resolve: `gatsby-plugin-mdx`,\\n      options: {\\n        extensions: [`.mdx`, `.md`],\\n      },\\n    },\\n    {\\n      resolve: `gatsby-source-filesystem`,\\n      options: {\\n        path: `${__dirname}/posts`,\\n        name: `posts`,\\n      },\\n    },\\n  ],\\n};\\n\")), mdx(\"h2\", {\n    \"id\": \"query-data-from-graphql\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#query-data-from-graphql\",\n    \"aria-label\": \"query data from graphql permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Query data from GraphQL\"), mdx(\"p\", null, \"Ok now you can see what the \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.gatsbyjs.org/packages/gatsby-source-filesystem/\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"gatsby-source-filesystem\"), \" and\\n\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.gatsbyjs.org/packages/gatsby-plugin-mdx/\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"gatsby-plugin-mdx\"), \" have done for us. You can now go to the Gatsby\\nGraphQL GraphiQL explorer and check out the data:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-graphql\"\n  }), \"{\\n  allMdx {\\n    nodes {\\n      frontmatter {\\n        title\\n        date\\n      }\\n    }\\n  }\\n}\\n\")), mdx(YouTube, {\n    youTubeId: \"MPNJu24ad_s\",\n    mdxType: \"YouTube\"\n  }), mdx(\"h2\", {\n    \"id\": \"site-metadata\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#site-metadata\",\n    \"aria-label\": \"site metadata permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Site Metadata\"), mdx(\"p\", null, \"When you want to reuse common pieces of data across the site (for\\nexample, your site title), you can store that data in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"siteMetadata\"), \",\\nyou touched on this when defining the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-config.js\"), \", now you\\u2019re\\ngoing to separate this out from the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"module.exports\"), \", why? It will be\\nnicer to reason about once the config is filled with plugins. At the\\ntop of \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-config.js\"), \" add a new object variable for the site\\nmetadata:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"const siteMetadata = {\\n  title: `The Localhost Blog`,\\n  description: `This is my coding blog where I write about my coding journey.`,\\n};\\n\")), mdx(\"p\", null, \"Now query the Site Metadata with GraphQL.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-graphql\"\n  }), \"{\\n  site {\\n    siteMetadata {\\n      title\\n      description\\n    }\\n  }\\n}\\n\")), mdx(\"h2\", {\n    \"id\": \"site-metadata-hook\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#site-metadata-hook\",\n    \"aria-label\": \"site metadata hook permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Site metadata hook\"), mdx(\"p\", null, \"Ok, so, that\\u2019s cool n\\u2019 all but how am I meant to use it? Well do some\\nof the code stuff and make a React hook so you can get your site data\\nin any component you need it.\"), mdx(\"p\", null, \"Create a folder to keep all your hooks in and create a file for our\\nhook, in the terminal do:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"mkdir src/hooks\\ntouch src/hooks/useSiteMetadata.js\\n\")), mdx(\"p\", null, \"Ok, and in your newly created file were going to use the Gatsby\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"useStaticQuery\"), \" hook to make your own hook:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"import { graphql, useStaticQuery } from 'gatsby';\\n\\nexport const useSiteMetadata = () => {\\n  const { site } = useStaticQuery(\\n    graphql`\\n      query SITE_METADATA_QUERY {\\n        site {\\n          siteMetadata {\\n            title\\n            description\\n          }\\n        }\\n      }\\n    `\\n  );\\n  return site.siteMetadata;\\n};\\n\")), mdx(\"p\", null, \"Now you can use this hook anywhere in your site, so do that now in\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"src/pages/index.js\"), \":\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import React from 'react';\\nimport { useSiteMetadata } from '../hooks/useSiteMetadata';\\n\\nexport default () => {\\n  const { title, description } = useSiteMetadata();\\n  return (\\n    <>\\n      <h1>{title}</h1>\\n      <p>{description}</p>\\n    </>\\n  );\\n};\\n\")), mdx(YouTube, {\n    youTubeId: \"TfycpV4yyqY\",\n    mdxType: \"YouTube\"\n  }), mdx(\"h2\", {\n    \"id\": \"styling\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#styling\",\n    \"aria-label\": \"styling permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Styling\"), mdx(\"p\", null, \"You\\u2019re going to use styled-components for styling, styled-components\\n(for me) help with scoping styles in your components. Time to go over\\nthe basics now.\"), mdx(\"h3\", {\n    \"id\": \"install-styled-components\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h3\"\n  }, {\n    \"href\": \"#install-styled-components\",\n    \"aria-label\": \"install styled components permalink\",\n    \"className\": \"anchor-toc 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  })))), \"install styled-components\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"yarn add gatsby-plugin-styled-components styled-components babel-plugin-styled-components\\n\")), mdx(\"p\", null, \"So, what was all that I just installed?\"), mdx(\"p\", null, \"The babel plugin is for automatic naming of components to help with\\ndebugging.\"), mdx(\"p\", null, \"The Gatsby plugin is for built-in server-side rendering support.\"), mdx(\"h3\", {\n    \"id\": \"configure\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h3\"\n  }, {\n    \"href\": \"#configure\",\n    \"aria-label\": \"configure permalink\",\n    \"className\": \"anchor-toc 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\"), mdx(\"p\", null, \"Ok, with that detailed explanation out of the way, configure them in\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-config.js\"), \":\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\",\n    \"metastring\": \"{1-4,7,9}\",\n    \"{1-4,7,9}\": true\n  }), \"const siteMetadata = {\\n  title: `The Localhost Blog`,\\n  description: `This is my coding blog where I write about my coding journey.`,\\n};\\n\\nmodule.exports = {\\n  siteMetadata: siteMetadata,\\n  plugins: [\\n    `gatsby-plugin-styled-components`,\\n    {\\n      resolve: `gatsby-plugin-mdx`,\\n      options: {\\n        extensions: [`.mdx`, `.md`],\\n      },\\n    },\\n    {\\n      resolve: `gatsby-source-filesystem`,\\n      options: {\\n        path: `${__dirname}/posts`,\\n        name: `posts`,\\n      },\\n    },\\n  ],\\n};\\n\")), mdx(\"p\", null, \"Ok, time to go over a styled component, in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"index.js\"), \" you\\u2019re going to\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"import styled from 'styled-components'\"), \" and create a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"StyledH1\"), \"\\nvariable.\"), mdx(\"p\", null, \"So, you\\u2019re using the variable to wrap your \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"{title}\"), \" that you\\u2019re\\ndestructuring from the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"useSiteMetadata\"), \" hook you made previously.\"), mdx(\"p\", null, \"For this example make it the now iconic Gatsby \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"rebeccapurple\"), \".\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\",\n    \"metastring\": \"{2-3,5-7,10-16}\",\n    \"{2-3,5-7,10-16}\": true\n  }), \"import React from 'react';\\nimport styled from 'styled-components';\\nimport { useSiteMetadata } from '../hooks/useSiteMetadata';\\n\\nconst StyledH1 = styled.h1`\\n  color: rebeccapurple;\\n`;\\n\\nexport default () => {\\n  const { title, description } = useSiteMetadata();\\n  return (\\n    <>\\n      <StyledH1>{title}</StyledH1>\\n      <p>{description}</p>\\n    </>\\n  );\\n};\\n\")), mdx(\"p\", null, \"That is styled-components on a very basic level, basically create the\\nstyling you want for your page elements you\\u2019re creating in the JSX.\"), mdx(YouTube, {\n    youTubeId: \"41aNkb2tLyg\",\n    mdxType: \"YouTube\"\n  }), mdx(\"h2\", {\n    \"id\": \"layout\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#layout\",\n    \"aria-label\": \"layout permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Layout\"), mdx(\"p\", null, \"Gatsby doesn\\u2019t apply any layouts by default but instead uses the way\\nyou can compose React components for the layout, meaning it\\u2019s up to\\nyou how you want to layout what your building with Gatsby. In this\\nguide were going to initially create a basic layout component that\\nyou\\u2019ll add to as you go along. For more detail on layout components\\ntake a look at the Gatsby \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.gatsbyjs.org/docs/layout-components/\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"layout components\"), \" page.\"), mdx(\"p\", null, \"Ok, so now you\\u2019re going to refactor the home page\\n(\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"src/pages/index.js\"), \") a little and make some components for your blog\\nlayout and header. In the terminal create a components directory and a\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Header\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Layout\"), \" component:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"mkdir src/components\\ntouch src/components/Header.js src/components/Layout.js\\n\")), mdx(\"p\", null, \"Now to move the title and description from \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"src/pages/index.js\"), \" to the\\nnewly created \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"src/components/Header.js\"), \" component, destructuring\\nprops for the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"siteTitle\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"siteDescription\"), \", you\\u2019ll pass these\\nfrom the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Layout\"), \" component to here. You\\u2019re going to add Gatsby Link\\nto this so users can click on the header to go back to the home page.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import { Link } from 'gatsby';\\nimport React from 'react';\\n\\nexport const Header = ({ siteTitle, siteDescription }) => (\\n  <Link to=\\\"/\\\">\\n    <h1>{siteTitle}</h1>\\n    <p>{siteDescription}</p>\\n  </Link>\\n);\\n\")), mdx(\"p\", null, \"Now to the Layout component, this is going to be a basic wrapper\\ncomponent for now, you\\u2019re going to use your site metadata hook for the\\ntitle and description and pass them to the header component and return\\nthe children of the wrapper (\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Layout\"), \").\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import React from 'react';\\nimport { useSiteMetadata } from '../hooks/useSiteMetadata';\\nimport { Header } from './Header';\\n\\nexport const Layout = ({ children }) => {\\n  const { title, description } = useSiteMetadata();\\n  return (\\n    <>\\n      <Header siteTitle={title} siteDescription={description} />\\n      {children}\\n    </>\\n  );\\n};\\n\")), mdx(\"p\", null, \"Now to add the slightest of styles for some alignment for\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"src/components/Layout.js\"), \", create an \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"AppStyles\"), \" styled component and\\nmake it the main wrapper of your \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Layout\"), \".\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import React from 'react';\\nimport styled from 'styled-components';\\nimport { useSiteMetadata } from '../hooks/useSiteMetadata';\\nimport { Header } from './Header';\\n\\nconst AppStyles = styled.main`\\n  width: 800px;\\n  margin: 0 auto;\\n`;\\n\\nexport const Layout = ({ children }) => {\\n  const { title, description } = useSiteMetadata();\\n  return (\\n    <AppStyles>\\n      <Header siteTitle={title} siteDescription={description} />\\n      {children}\\n    </AppStyles>\\n  );\\n};\\n\")), mdx(\"p\", null, \"Ok, now refactor your homepage (\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"src/pages/index.js\"), \") with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Layout\"), \".\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import React from 'react';\\nimport { Layout } from '../components/Layout';\\n\\nexport default () => {\\n  return (\\n    <>\\n      <Layout />\\n    </>\\n  );\\n};\\n\")), mdx(YouTube, {\n    youTubeId: \"Ase7bjxtQ3w\",\n    mdxType: \"YouTube\"\n  }), mdx(\"h2\", {\n    \"id\": \"index-page-posts-query\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#index-page-posts-query\",\n    \"aria-label\": \"index page posts query permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Index page posts query\"), mdx(\"p\", null, \"Ok, now you can take a look at getting some of the posts you\\u2019ve\\ncreated add them to the index page of your blog. You\\u2019re going to do\\nthat by creating a graphql query to list out the posts by title, order\\nby date and add an excerpt of the post.\"), mdx(\"p\", null, \"The query will look something like this:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-graphql\"\n  }), \"{\\n  allMdx {\\n    nodes {\\n      id\\n      excerpt(pruneLength: 250)\\n      frontmatter {\\n        title\\n        date\\n      }\\n    }\\n  }\\n}\\n\")), mdx(\"p\", null, \"If you put that into the GraphiQL GUI though you\\u2019ll notice that the\\nposts aren\\u2019t in any given order, so now add a sort to this you\\u2019ll also\\nadd in a filter for posts that are marked as published or not.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-graphql\"\n  }), \"{\\n  allMdx(\\n    sort: { fields: [frontmatter___date], order: DESC }\\n    filter: { frontmatter: { published: { eq: true } } }\\n  ) {\\n    nodes {\\n      id\\n      excerpt(pruneLength: 250)\\n      frontmatter {\\n        title\\n        date\\n      }\\n    }\\n  }\\n}\\n\")), mdx(\"p\", null, \"On the homepage (\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"src/pages/index.js\"), \") you\\u2019re going to use the query\\nwe just put together to get a list of published posts in date order;\\nadd the following to the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"index.js\"), \" file:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import { graphql } from 'gatsby';\\nimport React from 'react';\\nimport { Layout } from '../components/Layout';\\n\\nexport default ({ data }) => {\\n  return (\\n    <>\\n      <Layout>\\n        {data.allMdx.nodes.map(({ excerpt, frontmatter }) => (\\n          <>\\n            <h1>{frontmatter.title}</h1>\\n            <p>{frontmatter.date}</p>\\n            <p>{excerpt}</p>\\n          </>\\n        ))}\\n      </Layout>\\n    </>\\n  );\\n};\\n\\nexport const query = graphql`\\n  query SITE_INDEX_QUERY {\\n    allMdx(\\n      sort: { fields: [frontmatter___date], order: DESC }\\n      filter: { frontmatter: { published: { eq: true } } }\\n    ) {\\n      nodes {\\n        id\\n        excerpt(pruneLength: 250)\\n        frontmatter {\\n          title\\n          date\\n        }\\n      }\\n    }\\n  }\\n`;\\n\")), mdx(\"p\", null, \"Woah! WTF was all that yo!?\"), mdx(\"p\", null, \"Ok, you\\u2019re looping through the data passed into the component via the\\nGraphQL query. Gatsby \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"graphql\"), \" runs the query (\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"SITE_INDEX_QUERY\"), \") at\\nruntime and gives us the results as props to your component via the\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"data\"), \" prop.\"), mdx(YouTube, {\n    youTubeId: \"2GDbxZ0mHbM\",\n    mdxType: \"YouTube\"\n  }), mdx(\"h2\", {\n    \"id\": \"slugs-and-paths\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#slugs-and-paths\",\n    \"aria-label\": \"slugs and paths permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Slugs and Paths\"), mdx(\"p\", null, \"Gatsby source filesystem will help with the creation of slugs (URL\\npaths for the posts you\\u2019re creating) in Gatsby node you\\u2019re going to\\ncreate the slugs for your posts.\"), mdx(\"p\", null, \"First up you\\u2019re going to need to create a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-node.js\"), \" file:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"touch gatsby-node.js\\n\")), mdx(\"p\", null, \"This will create the file path (URL) for each of the blog posts.\"), mdx(\"p\", null, \"You\\u2019re going to be using the Gatsby Node API \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"onCreateNode\"), \" and\\ndestructuring out \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"node\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"actions\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"getNode\"), \" for use in creating\\nthe file locations and associated value.\"), 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, \"Now to help visualise some of the data being passed into the\\ncomponents you\\u2019re going to use \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/wesbos/dump\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"Dump.js\"), \" for debugging the data.\\nThanks to Wes Bos for the super handy \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/wesbos/dump\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"Dump.js\"), \" component.\"), mdx(\"p\", null, \"To get the component set up, create a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Dump.js\"), \" file in your\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"src\\\\components\"), \" folder and copypasta the code from the linked GitHub\\npage.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"touch /src/components/Dump.js\\n\")), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import React from 'react';\\n\\nconst Dump = props => (\\n  <div\\n    style={{\\n      fontSize: 20,\\n      border: '1px solid #efefef',\\n      padding: 10,\\n      background: 'white',\\n    }}\\n  >\\n    {Object.entries(props).map(([key, val]) => (\\n      <pre key={key}>\\n        <strong style={{ color: 'white', background: 'red' }}>\\n          {key} \\uD83D\\uDCA9\\n        </strong>\\n        {JSON.stringify(val, '', ' ')}\\n      </pre>\\n    ))}\\n  </div>\\n);\\n\\nexport default Dump;\\n\")), mdx(\"p\", null, \"Now you can use the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Dump\"), \" component anywhere in your project. To\\ndemonstrate, use it with the index page \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"data\"), \" to see the output.\"), mdx(\"p\", null, \"So in the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"src/pages/index.js\"), \" you\\u2019re going to import the Dump\\ncomponent and pass in the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"data\"), \" prop and see what the output looks\\nlike.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import { graphql } from 'gatsby';\\nimport React from 'react';\\nimport Dump from '../components/Dump';\\nimport { Layout } from '../components/Layout';\\n\\nexport default ({ data }) => {\\n  return (\\n    <>\\n      <Layout>\\n        <Dump data={data} />\\n        {data.allMdx.nodes.map(({ excerpt, frontmatter }) => (\\n          <>\\n            <h1>{frontmatter.title}</h1>\\n            <p>{frontmatter.date}</p>\\n            <p>{excerpt}</p>\\n          </>\\n        ))}\\n      </Layout>\\n    </>\\n  );\\n};\\n\\nexport const query = graphql`\\n  query SITE_INDEX_QUERY {\\n    allMdx(\\n      sort: { fields: [frontmatter___date], order: DESC }\\n      filter: { frontmatter: { published: { eq: true } } }\\n    ) {\\n      nodes {\\n        id\\n        excerpt(pruneLength: 250)\\n        frontmatter {\\n          title\\n          date\\n        }\\n      }\\n    }\\n  }\\n`;\\n\")), mdx(YouTube, {\n    youTubeId: \"7eZZk7aJnUU\",\n    mdxType: \"YouTube\"\n  }), mdx(\"h2\", {\n    \"id\": \"link-paths\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#link-paths\",\n    \"aria-label\": \"link paths permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Link Paths\"), mdx(\"p\", null, \"Now you\\u2019ve created the paths you can link to them with Gatsby Link.\\nFirst you\\u2019ll need to add the slug to your \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"SITE_INDEX_QUERY\"), \" Then you\\ncan add gatsby \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Link\"), \" to \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"src/pages/index.js\"), \".\"), mdx(\"p\", null, \"You\\u2019re also going to create some styled-components for wrapping the\\nlist of posts and each individual post as well.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import { graphql, Link } from 'gatsby';\\nimport React from 'react';\\nimport styled from 'styled-components';\\nimport { Layout } from '../components/Layout';\\n\\nconst IndexWrapper = styled.main``;\\n\\nconst PostWrapper = styled.div``;\\n\\nexport default ({ data }) => {\\n  return (\\n    <Layout>\\n      <IndexWrapper>\\n        {data.allMdx.nodes.map(\\n          ({ id, excerpt, frontmatter, fields }) => (\\n            <PostWrapper key={id}>\\n              <Link to={fields.slug}>\\n                <h1>{frontmatter.title}</h1>\\n                <p>{frontmatter.date}</p>\\n                <p>{excerpt}</p>\\n              </Link>\\n            </PostWrapper>\\n          )\\n        )}\\n      </IndexWrapper>\\n    </Layout>\\n  );\\n};\\n\\nexport const query = graphql`\\n  query SITE_INDEX_QUERY {\\n    allMdx(\\n      sort: { fields: [frontmatter___date], order: DESC }\\n      filter: { frontmatter: { published: { eq: true } } }\\n    ) {\\n      nodes {\\n        id\\n        excerpt(pruneLength: 250)\\n        frontmatter {\\n          title\\n          date\\n        }\\n        fields {\\n          slug\\n        }\\n      }\\n    }\\n  }\\n`;\\n\")), mdx(\"h2\", {\n    \"id\": \"adding-a-blog-post-template\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#adding-a-blog-post-template\",\n    \"aria-label\": \"adding a blog post template permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Adding a Blog Post Template\"), mdx(\"p\", null, \"Now you have the links pointing to the blog posts you currently have\\nno file associated with the path, so clicking a link will give you a\\n404 and the built in gatsby 404 will list all the pages available in\\nthe project, currently only the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"/\"), \" index/homepage.\"), mdx(\"p\", null, \"So, for each one of your blog posts you\\u2019re going to use a template\\nthat will contain, the information you need to make up your blog post.\\nTo start, create a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"templates\"), \" directory and template file for that\\nwith:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"mkdir -p src/templates\\ntouch src/templates/blogPostTemplate.js\\n\")), mdx(\"p\", null, \"For now you\\u2019re going to scaffold out a basic template, you\\u2019ll be\\nadding data to this shortly:\"), 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      <p>post here</p>\\n    </>\\n  );\\n};\\n\")), mdx(\"p\", null, \"To populate the template you\\u2019ll need to use Gatsby node to create your\\npages.\"), mdx(\"p\", null, \"Gatsby Node has many internal APIs available to us, for this example\\nyou\\u2019re going to be using the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"createPages\"), \" API.\"), mdx(\"p\", null, \"More details on Gatsby \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"createPages\"), \" API can be found on the Gatsby\\ndocs, details here:\\n\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.gatsbyjs.org/docs/node-apis/#createPages\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"https://www.gatsbyjs.org/docs/node-apis/#createPages\")), mdx(\"p\", null, \"In your \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-node.js\"), \" file you\\u2019re going to add in the following in\\naddition to the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"onCreateNode\"), \" export you did earlier.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"const { createFilePath } = require(`gatsby-source-filesystem`);\\nconst path = require(`path`);\\n\\nexports.createPages = ({ actions, graphql }) => {\\n  const { createPage } = actions;\\n  const blogPostTemplate = path.resolve(\\n    'src/templates/blogPostTemplate.js'\\n  );\\n\\n  return graphql(`\\n    {\\n      allMdx {\\n        nodes {\\n          fields {\\n            slug\\n          }\\n          frontmatter {\\n            title\\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    // create page for each mdx file\\n    posts.forEach(post => {\\n      createPage({\\n        path: post.fields.slug,\\n        component: blogPostTemplate,\\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, \"So the part that you need to pay particular attention to right now is\\nthe \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".forEach\"), \" loop where you\\u2019re using the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"createPage\"), \" function we\\ndestructured from the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"actions\"), \" object.\"), mdx(\"p\", null, \"This is where you pass the data needed by \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"blogPostTemplate\"), \" you\\ndefined earlier. You\\u2019re going to be adding more to the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"context\"), \" for\\npost navigation soon.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"// create page for each mdx node\\nposts.forEach(post => {\\n  createPage({\\n    path: post.fields.slug,\\n    component: blogPostTemplate,\\n    context: {\\n      slug: post.fields.slug,\\n    },\\n  });\\n});\\n\")), mdx(YouTube, {\n    youTubeId: \"OyQfIvXr4YA\",\n    mdxType: \"YouTube\"\n  }), mdx(\"h2\", {\n    \"id\": \"build-out-blog-post-template\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#build-out-blog-post-template\",\n    \"aria-label\": \"build out blog post template permalink\",\n    \"className\": \"anchor-toc 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 Blog Post Template\"), mdx(\"p\", null, \"Now you\\u2019re going to take the context information passed to the\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"blogPostTemplate.js\"), \" to make the blog post page.\"), mdx(\"p\", null, \"This is similar to the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"index.js\"), \" homepage whereas there\\u2019s GraphQL\\ndata used to create the page but in this instance the template uses a\\nvariable (also known as a parameter or an identifier) so you can query\\ndata specific to that given variable.\"), mdx(\"p\", null, \"Now quickly dig into that with a demo. In the GraphiQL GUI, create a\\nnamed query and define the variable you\\u2019re going to pass in:\"), 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  }\\n}\\n\")), mdx(\"p\", null, \"Here you\\u2019re defining the variable as slug with the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"$\"), \" denoting that\\nit\\u2019s a variable, you also need to define the variable type as (in this\\ncase) \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"String!\"), \" the exclamation after the type means that it has to be\\na string being passed into the query.\"), mdx(\"p\", null, \"Using \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"mdx\"), \" you\\u2019re going to filter on \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"fields\"), \" where the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"slug\"), \"\\nmatches the variable being passed into the query.\"), mdx(\"p\", null, \"Running the query now will show an error as there\\u2019s no variable being\\nfed into the query. If you look to the bottom of the query pane you\\nshould notice \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"QUERY VARIABLES\"), \", click on that to bring up the\\nvariables pane.\"), mdx(\"p\", null, \"This is where you can add in one of the post paths you created\\nearlier, if you have your dev server up and running go to one of the\\nposts and take the path and paste it into the quotes \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"\\\"\\\"\"), \" and try\\nrunning the query again.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-graphql\"\n  }), \"{\\n  \\\"slug\\\": \\\"/2019/2019-06-20-third-post/\\\"\\n}\\n\")), mdx(\"p\", null, \"Time to use that data to make the post, you\\u2019re going to add \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"body\"), \" to\\nthe query and have that at the bottom of your page file.\"), mdx(\"p\", null, \"Right now you\\u2019re going to add create a simple react component that\\nwill display the data you have queried.\"), mdx(\"p\", null, \"Destructuring the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"frontmatter\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"body\"), \" from the GraphQL query,\\nyou\\u2019ll get the Title and the Data from the frontmatter object and wrap\\nthe \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"body\"), \" in the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"MDXRenderer\"), \".\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import { graphql } from 'gatsby';\\nimport { MDXRenderer } from 'gatsby-plugin-mdx';\\nimport React from 'react';\\nimport { Layout } from '../components/Layout';\\n\\nexport default ({ data }) => {\\n  const { frontmatter, body } = data.mdx;\\n  return (\\n    <Layout>\\n      <h1>{frontmatter.title}</h1>\\n      <p>{frontmatter.date}</p>\\n      <MDXRenderer>{body}</MDXRenderer>\\n    </Layout>\\n  );\\n};\\n\\nexport const query = graphql`\\n  query PostsBySlug($slug: String!) {\\n    mdx(fields: { slug: { eq: $slug } }) {\\n      body\\n      frontmatter {\\n        title\\n        date(formatString: \\\"YYYY MMMM Do\\\")\\n      }\\n    }\\n  }\\n`;\\n\")), mdx(\"p\", null, \"If you haven\\u2019t done so already now would be a good time to restart\\nyour dev server.\"), mdx(\"p\", null, \"Now you can click on one of the post links and see your blog post\\ntemplate in all it\\u2019s basic glory!\"), mdx(YouTube, {\n    youTubeId: \"S7cnkRoCjsc\",\n    mdxType: \"YouTube\"\n  }), mdx(\"h2\", {\n    \"id\": \"previous-and-next\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#previous-and-next\",\n    \"aria-label\": \"previous and next permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Previous and Next\"), mdx(\"p\", null, \"Coolio! Now you have your basic ass blog where you can list available\\npost and click a link to see the full post in a predefined template.\\nOnce you\\u2019re in a post you have to navigate back to the home page to\\npick out a new post to read. In this section you\\u2019re going to work on\\nadding in some previous and next navigation.\"), mdx(\"p\", null, \"Remember the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".forEach\"), \" snippet you looked at earlier? That\\u2019s where\\nyou\\u2019re going to pass some additional context to the page by selecting\\nout the previous and next posts.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"// create page for each mdx node\\nposts.forEach((post, index) => {\\n  const previous =\\n    index === posts.length - 1 ? null : posts[index + 1];\\n  const next = index === 0 ? null : posts[index - 1];\\n\\n  createPage({\\n    path: post.fields.slug,\\n    component: blogPostTemplate,\\n    context: {\\n      slug: post.fields.slug,\\n      previous,\\n      next,\\n    },\\n  });\\n});\\n\")), mdx(\"p\", null, \"So this should now match up with the query you have on the homepage\\n(\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"src/pages/index.js\"), \") except you currently have no filter or sort\\napplied here so do that now in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-node.js\"), \" and apply the same\\nfilters as on the homepage query:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"const { createFilePath } = require(`gatsby-source-filesystem`);\\nconst path = require(`path`);\\n\\nexports.createPages = ({ actions, graphql }) => {\\n  const { createPage } = actions;\\n  const blogPostTemplate = path.resolve(\\n    'src/templates/blogPostTemplate.js'\\n  );\\n\\n  return graphql(`\\n    {\\n      allMdx(\\n        sort: { fields: [frontmatter___date], order: DESC }\\n        filter: { frontmatter: { published: { eq: true } } }\\n      ) {\\n        nodes {\\n          fields {\\n            slug\\n          }\\n          frontmatter {\\n            title\\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    // create page for each mdx node\\n    posts.forEach((post, index) => {\\n      const previous =\\n        index === posts.length - 1 ? null : posts[index + 1];\\n      const next = index === 0 ? null : posts[index - 1];\\n\\n      createPage({\\n        path: post.fields.slug,\\n        component: blogPostTemplate,\\n        context: {\\n          slug: post.fields.slug,\\n          previous,\\n          next,\\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, \"Now you will be able to expose the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"previous\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"next\"), \" objects\\npassed in as context from Gatsby node.\"), mdx(\"p\", null, \"You can destructure \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"previous\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"next\"), \" from \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"pageContext\"), \" and for\\nnow pop them into your super handy \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Dump\"), \" component to take a look at\\ntheir contents.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import { graphql } from 'gatsby';\\nimport { MDXRenderer } from 'gatsby-plugin-mdx';\\nimport React from 'react';\\nimport Dump from '../components/Dump';\\nimport { Layout } from '../components/Layout';\\n\\nexport default ({ data, pageContext }) => {\\n  const { frontmatter, body } = data.mdx;\\n  const { previous, next } = pageContext;\\n  return (\\n    <Layout>\\n      <Dump previous={previous} />\\n      <Dump next={next} />\\n      <h1>{frontmatter.title}</h1>\\n      <p>{frontmatter.date}</p>\\n      <MDXRenderer>{body}</MDXRenderer>\\n    </Layout>\\n  );\\n};\\n\\nexport const query = graphql`\\n  query PostsBySlug($slug: String!) {\\n    mdx(fields: { slug: { eq: $slug } }) {\\n      body\\n      frontmatter {\\n        title\\n        date(formatString: \\\"YYYY MMMM Do\\\")\\n      }\\n    }\\n  }\\n`;\\n\")), mdx(\"p\", null, \"Add in previous and next navigation, this is a couple of ternary\\noperations, if the variable is empty then return \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"null\"), \" else render a\\nGatsby \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Link\"), \" component with the page slug and the frontmatter title:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import { graphql, Link } from 'gatsby';\\nimport { MDXRenderer } from 'gatsby-plugin-mdx';\\nimport React from 'react';\\nimport Dump from '../components/Dump';\\nimport { Layout } from '../components/Layout';\\n\\nexport default ({ data, pageContext }) => {\\n  const { frontmatter, body } = data.mdx;\\n  const { previous, next } = pageContext;\\n  return (\\n    <Layout>\\n      <Dump previous={previous} />\\n      <Dump next={next} />\\n      <h1>{frontmatter.title}</h1>\\n      <p>{frontmatter.date}</p>\\n      <MDXRenderer>{body}</MDXRenderer>\\n      {previous === false ? null : (\\n        <>\\n          {previous && (\\n            <Link to={previous.fields.slug}>\\n              <p>{previous.frontmatter.title}</p>\\n            </Link>\\n          )}\\n        </>\\n      )}\\n      {next === false ? null : (\\n        <>\\n          {next && (\\n            <Link to={next.fields.slug}>\\n              <p>{next.frontmatter.title}</p>\\n            </Link>\\n          )}\\n        </>\\n      )}\\n    </Layout>\\n  );\\n};\\n\\nexport const query = graphql`\\n  query PostsBySlug($slug: String!) {\\n    mdx(fields: { slug: { eq: $slug } }) {\\n      body\\n      frontmatter {\\n        title\\n        date(formatString: \\\"YYYY MMMM Do\\\")\\n      }\\n    }\\n  }\\n`;\\n\")), mdx(YouTube, {\n    youTubeId: \"AjLimYEwDOk\",\n    mdxType: \"YouTube\"\n  }), mdx(\"h2\", {\n    \"id\": \"code-blocks\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#code-blocks\",\n    \"aria-label\": \"code blocks permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Code Blocks\"), mdx(\"p\", null, \"Now to add some syntax highlighting for adding code blocks to your\\nblog pages. To do that you\\u2019re going to add dependencies for\\n\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/FormidableLabs/prism-react-renderer\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"prism-react-renderer\"), \" and \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/FormidableLabs/react-live\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"react-live\"), \" and you\\u2019ll also create the\\nfiles you\\u2019re going to need to use them:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"yarn add prism-react-renderer react-live\\ntouch root-wrapper.js gatsby-ssr.js gatsby-browser.js\\n\")), mdx(\"p\", null, \"You\\u2019ll come onto \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"react-live\"), \" soon for now you\\u2019re going to get\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"prism-react-render\"), \" up and running for syntax highlighting for any\\ncode you\\u2019re going to add to the blog, but before that you\\u2019re going to\\ngo over the root wrapper concept.\"), mdx(\"p\", null, \"So, to change the rendering of a page element, such as a heading or a\\ncode block you\\u2019re going to need to use the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"MDXProvider\"), \", the\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"MDXProvider\"), \" is a component you can use anywhere higher in the React\\ncomponent tree than the MDX content you want to render.\"), mdx(\"p\", null, \"Gatsby browser and a Gatsby SSR both have \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"wrapRootElement\"), \" available\\nto them and that is as high up the tree as you can get so you\\u2019re going\\nto create the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"root-wrapper.js\"), \" file and add out elements you want to\\noverride there and import it into both \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-browser.js\"), \" and\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-ssr.js\"), \" so you\\u2019re not duplicating code.\"), mdx(\"p\", null, \"Before you go any further I want to add that there is a top quality\\n\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://egghead.io/lessons/vue-js-introduction-to-mdx?pl=building-websites-with-mdx-and-gatsby-161e9529\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"egghead.io playlist\"), \" resource for using MDX with Gatsby by Chris\\n\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://twitter.com/chrisbiscardi\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"Chris Biscardi\"), \" there\\u2019s a ton of useful information in there on MDX\\nin Gatsby.\"), mdx(\"p\", null, \"Ok, first up you\\u2019re going to import the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"root-wrapper.js\"), \" file into\\nboth \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-browser.js\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-ssr.js\"), \", in both code modules\\npaste the following:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"import { wrapRootElement as wrap } from './root-wrapper';\\n\\nexport const wrapRootElement = wrap;\\n\")), mdx(\"p\", null, \"Ok, now you can work on the code that will be used in both modules.\\nMDX allows you to control the rendering of page elements in your\\nmarkdown. \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"MDXProvider\"), \" is used to give to give React components to\\noverride the markdown page elements.\"), mdx(\"p\", null, \"Quick demonstration, in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"root-wrapper.js\"), \" add the following:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import { MDXProvider } from '@mdx-js/react';\\nimport React from 'react';\\n\\nconst components = {\\n  h2: ({ children }) => (\\n    <h2 style={{ color: 'rebeccapurple' }}>{children}</h2>\\n  ),\\n  'p.inlineCode': props => (\\n    <code style={{ backgroundColor: 'lightgray' }} {...props} />\\n  ),\\n};\\n\\nexport const wrapRootElement = ({ element }) => (\\n  <MDXProvider components={components}>{element}</MDXProvider>\\n);\\n\")), mdx(\"p\", null, \"You\\u2019re now overriding any \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"h2\"), \" in your rendered markdown along with\\nany \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"code\"), \" blocks (that\\u2019s words wrapped in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"`backticks`\"), \").\"), mdx(YouTube, {\n    youTubeId: \"kN8ld7iLQso\",\n    mdxType: \"YouTube\"\n  }), mdx(\"p\", null, \"Ok, now for the syntax highlighting, create a post with a block of\\ncode in it:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"mkdir posts/2019-07-01-code-blocks\\ntouch posts/2019-07-01-code-blocks/index.mdx\\n\")), mdx(\"p\", null, \"Paste in some content:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-markdown\"\n  }), \"---\\ntitle: Code Blocks\\ndate: 2019-07-01\\npublished: true\\n---\\n\\n## Yes! Some code!\\n\\nHere is the `Dump` component!\\n\\n```jsx\\nimport React from 'react';\\n\\nconst Dump = props => (\\n  <div\\n    style={{\\n      fontSize: 20,\\n      border: '1px solid #efefef',\\n      padding: 10,\\n      background: 'white',\\n    }}\\n  >\\n    {Object.entries(props).map(([key, val]) => (\\n      <pre key={key}>\\n        <strong style={{ color: 'white', background: 'red' }}>\\n          {key} \\uD83D\\uDCA9\\n        </strong>\\n        {JSON.stringify(val, '', ' ')}\\n      </pre>\\n    ))}\\n  </div>\\n);\\n\\nexport default Dump;\\n```\\n\")), mdx(\"p\", null, \"Ok, if you go to the \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/FormidableLabs/prism-react-renderer\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"prism-react-renderer\"), \" GitHub page and copy the\\nexample code into \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"root-wrapper.js\"), \" for the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"pre\"), \" element.\"), mdx(\"p\", null, \"You\\u2019re going to copy the provided code for highlighting to validate it\\nworks.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import { MDXProvider } from '@mdx-js/react';\\nimport Highlight, { defaultProps } from 'prism-react-renderer';\\nimport React from 'react';\\n\\nconst components = {\\n  h2: ({ children }) => (\\n    <h2 style={{ color: 'rebeccapurple' }}>{children}</h2>\\n  ),\\n  'p.inlineCode': props => (\\n    <code style={{ backgroundColor: 'lightgray' }} {...props} />\\n  ),\\n  pre: props => (\\n    <Highlight\\n      {...defaultProps}\\n      code={`\\n        (function someDemo() {\\n          var test = \\\"Hello World!\\\";\\n          console.log(test);\\n        })();\\n\\n        return () => <App />;\\n      `}\\n      language=\\\"jsx\\\"\\n    >\\n      {({\\n        className,\\n        style,\\n        tokens,\\n        getLineProps,\\n        getTokenProps,\\n      }) => (\\n        <pre className={className} style={style}>\\n          {tokens.map((line, i) => (\\n            <div {...getLineProps({ line, key: i })}>\\n              {line.map((token, key) => (\\n                <span {...getTokenProps({ token, key })} />\\n              ))}\\n            </div>\\n          ))}\\n        </pre>\\n      )}\\n    </Highlight>\\n  ),\\n};\\n\\nexport const wrapRootElement = ({ element }) => (\\n  <MDXProvider components={components}>{element}</MDXProvider>\\n);\\n\")), mdx(\"p\", null, \"Cool, cool! Now you want to replace the pasted in code example with\\nthe props of the child component of the pre component, you can do that\\nwith \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"props.children.props.children.trim()\"), \" \\uD83D\\uDE43.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import { MDXProvider } from '@mdx-js/react';\\nimport Highlight, { defaultProps } from 'prism-react-renderer';\\nimport React from 'react';\\n\\nconst components = {\\n  pre: props => (\\n    <Highlight\\n      {...defaultProps}\\n      code={props.children.props.children.trim()}\\n      language=\\\"jsx\\\"\\n    >\\n      {({\\n        className,\\n        style,\\n        tokens,\\n        getLineProps,\\n        getTokenProps,\\n      }) => (\\n        <pre className={className} style={style}>\\n          {tokens.map((line, i) => (\\n            <div {...getLineProps({ line, key: i })}>\\n              {line.map((token, key) => (\\n                <span {...getTokenProps({ token, key })} />\\n              ))}\\n            </div>\\n          ))}\\n        </pre>\\n      )}\\n    </Highlight>\\n  ),\\n};\\n\\nexport const wrapRootElement = ({ element }) => (\\n  <MDXProvider components={components}>{element}</MDXProvider>\\n);\\n\")), mdx(\"p\", null, \"Then to match the language, for now you\\u2019re going to add in a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"matches\"), \"\\nfunction to match the language class assigned to the code block.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import { MDXProvider } from '@mdx-js/react';\\nimport Highlight, { defaultProps } from 'prism-react-renderer';\\nimport React from 'react';\\n\\nconst components = {\\n  h2: ({ children }) => (\\n    <h2 style={{ color: 'rebeccapurple' }}>{children}</h2>\\n  ),\\n  'p.inlineCode': props => (\\n    <code style={{ backgroundColor: 'lightgray' }} {...props} />\\n  ),\\n  pre: props => {\\n    const className = props.children.props.className || '';\\n    const matches = className.match(/language-(?<lang>.*)/);\\n    return (\\n      <Highlight\\n        {...defaultProps}\\n        code={props.children.props.children.trim()}\\n        language={\\n          matches && matches.groups && matches.groups.lang\\n            ? matches.groups.lang\\n            : ''\\n        }\\n      >\\n        {({\\n          className,\\n          style,\\n          tokens,\\n          getLineProps,\\n          getTokenProps,\\n        }) => (\\n          <pre className={className} style={style}>\\n            {tokens.map((line, i) => (\\n              <div {...getLineProps({ line, key: i })}>\\n                {line.map((token, key) => (\\n                  <span {...getTokenProps({ token, key })} />\\n                ))}\\n              </div>\\n            ))}\\n          </pre>\\n        )}\\n      </Highlight>\\n    );\\n  },\\n};\\n\\nexport const wrapRootElement = ({ element }) => (\\n  <MDXProvider components={components}>{element}</MDXProvider>\\n);\\n\")), mdx(\"p\", null, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/FormidableLabs/prism-react-renderer\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"prism-react-renderer\"), \" comes with additional themes over the default\\ntheme which is \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/FormidableLabs/prism-react-renderer/blob/master/themes/duotoneDark.js\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"duotoneDark\"), \" you\\u2019re going to use \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/FormidableLabs/prism-react-renderer/blob/master/themes/nightOwl.js\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"nightOwl\"), \" in this\\nexample, feel free to take a look at \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/FormidableLabs/prism-react-renderer/blob/master/themes\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"the other examples\"), \" if you like.\"), mdx(\"p\", null, \"Import the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"theme\"), \" then use it in the props of the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Highlight\"), \"\\ncomponent.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import { MDXProvider } from '@mdx-js/react';\\nimport Highlight, { defaultProps } from 'prism-react-renderer';\\nimport theme from 'prism-react-renderer/themes/nightOwl';\\nimport React from 'react';\\n\\nconst components = {\\n  pre: props => {\\n    const className = props.children.props.className || '';\\n    const matches = className.match(/language-(?<lang>.*)/);\\n\\n    return (\\n      <Highlight\\n        {...defaultProps}\\n        code={props.children.props.children.trim()}\\n        language={\\n          matches && matches.groups && matches.groups.lang\\n            ? matches.groups.lang\\n            : ''\\n        }\\n        theme={theme}\\n      >\\n        {({\\n          className,\\n          style,\\n          tokens,\\n          getLineProps,\\n          getTokenProps,\\n        }) => (\\n          <pre className={className} style={style}>\\n            {tokens.map((line, i) => (\\n              <div {...getLineProps({ line, key: i })}>\\n                {line.map((token, key) => (\\n                  <span {...getTokenProps({ token, key })} />\\n                ))}\\n              </div>\\n            ))}\\n          </pre>\\n        )}\\n      </Highlight>\\n    );\\n  },\\n};\\n\\nexport const wrapRootElement = ({ element }) => (\\n  <MDXProvider components={components}>{element}</MDXProvider>\\n);\\n\")), mdx(YouTube, {\n    youTubeId: \"k6gI3jVxjKg\",\n    mdxType: \"YouTube\"\n  }), mdx(\"p\", null, \"Ok, now time to abstract this out into it\\u2019s own component so your\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"root-wrapper.js\"), \" isn\\u2019t so crowded.\"), mdx(\"p\", null, \"Make a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Code.js\"), \" component, move the code from \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"root-wrapper.js\"), \" into\\nthere\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"touch src/components/Code.js\\n\")), mdx(\"p\", null, \"Remember this?\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"Cool, cool! Now you want to replace the pasted in code example with\\nthe props of the child component of the pre component, you can do\\nthat with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"props.children.props.children.trim()\"), \" \\uD83D\\uDE43.\")), mdx(\"p\", null, \"If that \\u261D makes no real amount of sense for you (I\\u2019ve had to read it\\nmany, many times myself), don\\u2019t worry, now you\\u2019re going to dig into\\nthat a bit more for the creation of the code block component.\"), mdx(\"p\", null, \"So, for now in the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"components\"), \" you\\u2019re adding into the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"MDXProvider\"), \",\\ntake a look at the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"props\"), \" coming into the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"pre\"), \" element.\"), mdx(\"p\", null, \"Comment out the code you added earlier and add in a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"console.log\"), \":\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"pre: props => {\\n  console.log('=====================');\\n  console.log(props);\\n  console.log('=====================');\\n  return <pre />;\\n};\\n\")), mdx(\"p\", null, \"Now if you pop open the developer tools of your browser you can see\\nthe output.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {}), \"{children: {\\u2026}}\\n  children:\\n    $$typeof: Symbol(react.element)\\n    key: null\\n    props: {parentName: \\\"pre\\\", className: \\\"language-jsx\\\", originalType: \\\"code\\\", mdxType: \\\"code\\\", children: \\\"import React from 'react'\\u21B5\\u21B5const Dump = props => (\\u2026  </pre>\\u21B5    ))}\\u21B5  </div>\\u21B5)\\u21B5\\u21B5export default Dump\\u21B5\\\"}\\n    ref: null\\n    type: \\u0192 (re....\\n\")), mdx(\"p\", null, \"If you drill into the props of that output you can see the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"children\"), \"\\nof those props, if you take a look at the contents of that you will\\nsee that it is the code string for your code block, this is what\\nyou\\u2019re going to be passing into the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Code\"), \" component you\\u2019re about to\\ncreate. Other properties to note here are the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"className\"), \" and\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"mdxType\"), \".\"), mdx(\"p\", null, \"So, take the code you used earlier for \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Highlight\"), \", everything inside\\nand including the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"return\"), \" statement and paste it into the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Code.js\"), \"\\nmodule you created earlier.\"), mdx(\"p\", null, mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Highlight\"), \" requires several props:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"<Highlight\\n  {...defaultProps}\\n  code={codeString}\\n  language={language}\\n  theme={theme}\\n>\\n\")), mdx(\"p\", null, \"The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Code\"), \" module should look something like this now:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import Highlight, { defaultProps } from 'prism-react-renderer';\\nimport theme from 'prism-react-renderer/themes/nightOwl';\\nimport React from 'react';\\n\\nconst Code = ({ codeString, language }) => {\\n  return (\\n    <Highlight\\n      {...defaultProps}\\n      code={codeString}\\n      language={language}\\n      theme={theme}\\n    >\\n      {({\\n        className,\\n        style,\\n        tokens,\\n        getLineProps,\\n        getTokenProps,\\n      }) => (\\n        <pre className={className} style={style}>\\n          {tokens.map((line, i) => (\\n            <div {...getLineProps({ line, key: i })}>\\n              {line.map((token, key) => (\\n                <span {...getTokenProps({ token, key })} />\\n              ))}\\n            </div>\\n          ))}\\n        </pre>\\n      )}\\n    </Highlight>\\n  );\\n};\\n\\nexport default Code;\\n\")), mdx(\"p\", null, \"Back to the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"root-wrapper\"), \" where you\\u2019re going to pass the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"props\"), \"\\nneeded to the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Code\"), \" component.\"), mdx(\"p\", null, \"The first check you\\u2019re going to do is if the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"mdxType\"), \" is \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"code\"), \" then\\nyou can get the additional props you need to pass to your \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Code\"), \"\\ncomponent.\"), mdx(\"p\", null, \"You\\u2019re going to get \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"defaultProps\"), \" and the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"theme\"), \" from\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"prism-react-renderer\"), \" so all that\\u2019s needed is the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"code\"), \" and\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"language\"), \".\"), mdx(\"p\", null, \"The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"codeString\"), \" you can get from the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"props\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"children\"), \" by\\ndestructuring from the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"props\"), \" being passed into the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"pre\"), \" element.\\nThe \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"language\"), \" can either be the tag assigned to the meta property of\\nthe backticks, like \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"js\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"jsx\"), \" or equally empty, so you check for\\nthat with some JavaScript and also remove the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"language-\"), \" prefix, then\\npass in the elements \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"{...props}\"), \":\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"pre: ({ children: { props } }) => {\\n  if (props.mdxType === 'code') {\\n    return (\\n      <Code\\n        codeString={props.children.trim()}\\n        language={\\n          props.className && props.className.replace('language-', '')\\n        }\\n        {...props}\\n      />\\n    );\\n  }\\n};\\n\")), mdx(YouTube, {\n    youTubeId: \"m0tWxa9Ip5E\",\n    mdxType: \"YouTube\"\n  }), mdx(\"p\", null, \"Ok, now you\\u2019re back to where you were before abstracting out the\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Highlight\"), \" component to it\\u2019s own module. Add some additional styles\\nwith \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"styled-components\"), \" and replace the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"pre\"), \" with a styled \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Pre\"), \" and\\nyou can also add in some line numbers with a styled span and style\\nthat as well.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"import Highlight, { defaultProps } from 'prism-react-renderer';\\nimport theme from 'prism-react-renderer/themes/nightOwl';\\nimport React from 'react';\\nimport styled from 'styled-components';\\n\\nexport const Pre = styled.pre`\\n  text-align: left;\\n  margin: 1em 0;\\n  padding: 0.5em;\\n  overflow-x: auto;\\n  border-radius: 3px;\\n\\n  & .token-line {\\n    line-height: 1.3em;\\n    height: 1.3em;\\n  }\\n  font-family: 'Courier New', Courier, monospace;\\n`;\\n\\nexport const LineNo = styled.span`\\n  display: inline-block;\\n  width: 2em;\\n  user-select: none;\\n  opacity: 0.3;\\n`;\\n\\nconst Code = ({ codeString, language, ...props }) => {\\n  return (\\n    <Highlight\\n      {...defaultProps}\\n      code={codeString}\\n      language={language}\\n      theme={theme}\\n    >\\n      {({\\n        className,\\n        style,\\n        tokens,\\n        getLineProps,\\n        getTokenProps,\\n      }) => (\\n        <Pre className={className} style={style}>\\n          {tokens.map((line, i) => (\\n            <div {...getLineProps({ line, key: i })}>\\n              <LineNo>{i + 1}</LineNo>\\n              {line.map((token, key) => (\\n                <span {...getTokenProps({ token, key })} />\\n              ))}\\n            </div>\\n          ))}\\n        </Pre>\\n      )}\\n    </Highlight>\\n  );\\n};\\n\\nexport default Code;\\n\")), mdx(YouTube, {\n    youTubeId: \"PPH153kWpqc\",\n    mdxType: \"YouTube\"\n  }), mdx(\"h3\", {\n    \"id\": \"copy-code-to-clipboard\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h3\"\n  }, {\n    \"href\": \"#copy-code-to-clipboard\",\n    \"aria-label\": \"copy code to clipboard permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Copy code to clipboard\"), mdx(\"p\", null, \"What if you had some way of getting that props code string into the\\nclipboard?\"), mdx(\"p\", null, \"I had a look around and found the majority of the components available\\nfor this sort of thing expected an input until \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/gatsbyjs/gatsby/blob/master/www/src/utils/copy-to-clipboard.js\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"this\"), \" in the Gatsby\\nsource code. Which is creating the input for you \\uD83D\\uDC4C\"), mdx(\"p\", null, \"So, create a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"utils\"), \" directory and the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"copy-to-clipboard.js\"), \" file and\\nadd in the code from the Gatsby sourcue code.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"mkdir src/utils\\ntouch src/utils/copy-to-clipboard.js\\n\")), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"// https://github.com/gatsbyjs/gatsby/blob/master/www/src/utils/copy-to-clipboard.js\\n\\nexport const copyToClipboard = str => {\\n  const clipboard = window.navigator.clipboard;\\n  /*\\n   * fallback to older browsers (including Safari)\\n   * if clipboard API not supported\\n   */\\n  if (!clipboard || typeof clipboard.writeText !== `function`) {\\n    const textarea = document.createElement(`textarea`);\\n    textarea.value = str;\\n    textarea.setAttribute(`readonly`, true);\\n    textarea.setAttribute(`contenteditable`, true);\\n    textarea.style.position = `absolute`;\\n    textarea.style.left = `-9999px`;\\n    document.body.appendChild(textarea);\\n    textarea.select();\\n    const range = document.createRange();\\n    const sel = window.getSelection();\\n    sel.removeAllRanges();\\n    sel.addRange(range);\\n    textarea.setSelectionRange(0, textarea.value.length);\\n    document.execCommand(`copy`);\\n    document.body.removeChild(textarea);\\n\\n    return Promise.resolve(true);\\n  }\\n\\n  return clipboard.writeText(str);\\n};\\n\")), mdx(\"p\", null, \"Now you\\u2019re going to want a way to trigger copying the code to the\\nclipboard.\"), mdx(\"p\", null, \"Lets create a styled button but first add a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"position: relative;\"), \" to\\nthe \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Pre\"), \" component which will let us position the styled button:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"const CopyCode = styled.button`\\n  position: absolute;\\n  right: 0.25rem;\\n  border: 0;\\n  border-radius: 3px;\\n  margin: 0.25em;\\n  opacity: 0.3;\\n  &:hover {\\n    opacity: 1;\\n  }\\n`;\\n\")), mdx(\"p\", null, \"And now you need to use the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"copyToClipboard\"), \" function in the\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"onClick\"), \" of the button:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import Highlight, { defaultProps } from 'prism-react-renderer';\\nimport theme from 'prism-react-renderer/themes/nightOwl';\\nimport React from 'react';\\nimport styled from 'styled-components';\\nimport { copyToClipboard } from '../utils/copy-to-clipboard';\\n\\nexport const Pre = styled.pre`\\n  text-align: left;\\n  margin: 1rem 0;\\n  padding: 0.5rem;\\n  overflow-x: auto;\\n  border-radius: 3px;\\n\\n  & .token-line {\\n    line-height: 1.3rem;\\n    height: 1.3rem;\\n  }\\n  font-family: 'Courier New', Courier, monospace;\\n  position: relative;\\n`;\\n\\nexport const LineNo = styled.span`\\n  display: inline-block;\\n  width: 2rem;\\n  user-select: none;\\n  opacity: 0.3;\\n`;\\n\\nconst CopyCode = styled.button`\\n  position: absolute;\\n  right: 0.25rem;\\n  border: 0;\\n  border-radius: 3px;\\n  margin: 0.25em;\\n  opacity: 0.3;\\n  &:hover {\\n    opacity: 1;\\n  }\\n`;\\n\\nconst Code = ({ codeString, language }) => {\\n  const handleClick = () => {\\n    copyToClipboard(codeString);\\n  };\\n\\n  return (\\n    <Highlight\\n      {...defaultProps}\\n      code={codeString}\\n      language={language}\\n      theme={theme}\\n    >\\n      {({\\n        className,\\n        style,\\n        tokens,\\n        getLineProps,\\n        getTokenProps,\\n      }) => (\\n        <Pre className={className} style={style}>\\n          <CopyCode onClick={handleClick}>Copy</CopyCode>\\n          {tokens.map((line, i) => (\\n            <div {...getLineProps({ line, key: i })}>\\n              <LineNo>{i + 1}</LineNo>\\n              {line.map((token, key) => (\\n                <span {...getTokenProps({ token, key })} />\\n              ))}\\n            </div>\\n          ))}\\n        </Pre>\\n      )}\\n    </Highlight>\\n  );\\n};\\n\\nexport default Code;\\n\")), mdx(YouTube, {\n    youTubeId: \"j-EINXVe2WA\",\n    mdxType: \"YouTube\"\n  }), mdx(\"h2\", {\n    \"id\": \"react-live\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#react-live\",\n    \"aria-label\": \"react live permalink\",\n    \"className\": \"anchor-toc 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  })))), \"React live\"), mdx(\"p\", null, \"So with React Live you need to add two snippets to your \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Code.js\"), \"\\ncomponent.\"), mdx(\"p\", null, \"You\\u2019re going to import the components:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import {\\n  LiveEditor,\\n  LiveError,\\n  LivePreview,\\n  LiveProvider,\\n} from 'react-live';\\n\")), mdx(\"p\", null, \"Then ypu\\u2019re going to check if \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"react-live\"), \" has been added to the\\nlanguage tag on your mdx file via the props:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"if (props['react-live']) {\\n  return (\\n    <LiveProvider code={codeString} noInline={true} theme={theme}>\\n      <LiveEditor />\\n      <LiveError />\\n      <LivePreview />\\n    </LiveProvider>\\n  );\\n}\\n\")), mdx(\"p\", null, \"Here\\u2019s the full component:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"import Highlight, { defaultProps } from 'prism-react-renderer';\\nimport theme from 'prism-react-renderer/themes/nightOwl';\\nimport React from 'react';\\nimport {\\n  LiveEditor,\\n  LiveError,\\n  LivePreview,\\n  LiveProvider,\\n} from 'react-live';\\nimport styled from 'styled-components';\\nimport { copyToClipboard } from '../../utils/copy-to-clipboard';\\n\\nconst Pre = styled.pre`\\n  position: relative;\\n  text-align: left;\\n  margin: 1em 0;\\n  padding: 0.5em;\\n  overflow-x: auto;\\n  border-radius: 3px;\\n\\n  & .token-lline {\\n    line-height: 1.3em;\\n    height: 1.3em;\\n  }\\n  font-family: 'Courier New', Courier, monospace;\\n`;\\n\\nconst LineNo = styled.span`\\n  display: inline-block;\\n  width: 2em;\\n  user-select: none;\\n  opacity: 0.3;\\n`;\\n\\nconst CopyCode = styled.button`\\n  position: absolute;\\n  right: 0.25rem;\\n  border: 0;\\n  border-radius: 3px;\\n  margin: 0.25em;\\n  opacity: 0.3;\\n  &:hover {\\n    opacity: 1;\\n  }\\n`;\\n\\nexport const Code = ({ codeString, language, ...props }) => {\\n  if (props['react-live']) {\\n    return (\\n      <LiveProvider code={codeString} noInline={true} theme={theme}>\\n        <LiveEditor />\\n        <LiveError />\\n        <LivePreview />\\n      </LiveProvider>\\n    );\\n  }\\n\\n  const handleClick = () => {\\n    copyToClipboard(codeString);\\n  };\\n\\n  return (\\n    <Highlight\\n      {...defaultProps}\\n      code={codeString}\\n      language={language}\\n      theme={theme}\\n    >\\n      {({\\n        className,\\n        style,\\n        tokens,\\n        getLineProps,\\n        getTokenProps,\\n      }) => (\\n        <Pre className={className} style={style}>\\n          <CopyCode onClick={handleClick}>Copy</CopyCode>\\n          {tokens.map((line, i) => (\\n            <div {...getLineProps({ line, key: i })}>\\n              <LineNo>{i + 1}</LineNo>\\n              {line.map((token, key) => (\\n                <span {...getTokenProps({ token, key })} />\\n              ))}\\n            </div>\\n          ))}\\n        </Pre>\\n      )}\\n    </Highlight>\\n  );\\n};\\n\")), mdx(\"p\", null, \"To test this, add \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"react-live\"), \" next to the language on your \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Dump\"), \"\\ncomponent, so you have added to the blog post you made:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-text\"\n  }), \"```jsx react-live\\n\")), mdx(\"p\", null, \"Now you can edit the code directly, try changing a few things like\\nthis:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"const Dump = props => (\\n  <div\\n    style={{\\n      fontSize: 20,\\n      border: '1px solid #efefef',\\n      padding: 10,\\n      background: 'white',\\n    }}\\n  >\\n    {Object.entries(props).map(([key, val]) => (\\n      <pre key={key}>\\n        <strong style={{ color: 'white', background: 'red' }}>\\n          {key} \\uD83D\\uDCA9\\n        </strong>\\n        {JSON.stringify(val, '', ' ')}\\n      </pre>\\n    ))}\\n  </div>\\n);\\n\\nrender(<Dump props={['One', 'Two', 'Three', 'Four']} />);\\n\")), mdx(YouTube, {\n    youTubeId: \"AlOdd-TvqHE\",\n    mdxType: \"YouTube\"\n  }), mdx(\"h2\", {\n    \"id\": \"cover-image\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#cover-image\",\n    \"aria-label\": \"cover image permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Cover Image\"), mdx(\"p\", null, \"Now to add a cover image to go with each post, you\\u2019ll need to install\\na couple of packages to manage images in Gatsby.\"), mdx(\"p\", null, \"install:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"yarn add gatsby-transformer-sharp gatsby-plugin-sharp gatsby-remark-images gatsby-image\\n\")), mdx(\"p\", null, \"Now you should config \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-config.js\"), \" to include the newly added\\npackages. Remember to add \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-remark-images\"), \" to\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-plugin-mdx\"), \" as both a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsbyRemarkPlugins\"), \" option and as a\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"plugins\"), \" option.\"), mdx(\"p\", null, \"config:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"module.exports = {\\n  siteMetadata: siteMetadata,\\n  plugins: [\\n    `gatsby-plugin-styled-components`,\\n    `gatsby-transformer-sharp`,\\n    `gatsby-plugin-sharp`,\\n    {\\n      resolve: `gatsby-plugin-mdx`,\\n      options: {\\n        extensions: [`.mdx`, `.md`],\\n        gatsbyRemarkPlugins: [\\n          {\\n            resolve: `gatsby-remark-images`,\\n            options: {\\n              maxWidth: 590,\\n            },\\n          },\\n        ],\\n        plugins: [\\n          {\\n            resolve: `gatsby-remark-images`,\\n            options: {\\n              maxWidth: 590,\\n            },\\n          },\\n        ],\\n      },\\n    },\\n    {\\n      resolve: `gatsby-source-filesystem`,\\n      options: { path: `${__dirname}/posts`, name: `posts` },\\n    },\\n  ],\\n};\\n\")), mdx(\"p\", null, \"Add image to index query in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"src/pages.index.js\"), \":\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-graphql\"\n  }), \"cover {\\n  publicURL\\n  childImageSharp {\\n    sizes(\\n      maxWidth: 2000\\n      traceSVG: { color: \\\"#639\\\" }\\n    ) {\\n      ...GatsbyImageSharpSizes_tracedSVG\\n    }\\n  }\\n}\\n\")), mdx(\"p\", null, \"Fix up the date in the query too:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-graphql\"\n  }), \"date(formatString: \\\"YYYY MMMM Do\\\")\\n\")), mdx(\"p\", null, \"This will show the date as full year, full month and the day as a\\n\\u2018st\\u2019, \\u2018nd\\u2019, \\u2018rd\\u2019 and \\u2018th\\u2019. So if today\\u2019s date were 1970/01/01 it would\\nread 1970 January 1st.\"), mdx(\"p\", null, \"Add \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-image\"), \" use that in a styled component:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"const Image = styled(Img)`\\n  border-radius: 5px;\\n`;\\n\")), mdx(\"p\", null, \"Add some JavaScript to determine if there\\u2019s anything to render:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"{\\n  !!frontmatter.cover ? (\\n    <Image sizes={frontmatter.cover.childImageSharp.sizes} />\\n  ) : null;\\n}\\n\")), mdx(\"p\", null, \"Here\\u2019s what the full module should look like now:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"import { Link } from 'gatsby';\\nimport Img from 'gatsby-image';\\nimport React from 'react';\\nimport styled from 'styled-components';\\nimport { Layout } from '../components/Layout';\\n\\nconst IndexWrapper = styled.main``;\\n\\nconst PostWrapper = styled.div``;\\n\\nconst Image = styled(Img)`\\n  border-radius: 5px;\\n`;\\n\\nexport default ({ data }) => {\\n  return (\\n    <Layout>\\n      <IndexWrapper>\\n        {/* <Dump data={data}></Dump> */}\\n        {data.allMdx.nodes.map(\\n          ({ id, excerpt, frontmatter, fields }) => (\\n            <PostWrapper key={id}>\\n              <Link to={fields.slug}>\\n                {!!frontmatter.cover ? (\\n                  <Image\\n                    sizes={frontmatter.cover.childImageSharp.sizes}\\n                  />\\n                ) : null}\\n                <h1>{frontmatter.title}</h1>\\n                <p>{frontmatter.date}</p>\\n                <p>{excerpt}</p>\\n              </Link>\\n            </PostWrapper>\\n          )\\n        )}\\n      </IndexWrapper>\\n    </Layout>\\n  );\\n};\\n\\nexport const query = graphql`\\n  query SITE_INDEX_QUERY {\\n    allMdx(\\n      sort: { fields: [frontmatter___date], order: DESC }\\n      filter: { frontmatter: { published: { eq: true } } }\\n    ) {\\n      nodes {\\n        id\\n        excerpt(pruneLength: 250)\\n        frontmatter {\\n          title\\n          date(formatString: \\\"YYYY MMMM Do\\\")\\n          cover {\\n            publicURL\\n            childImageSharp {\\n              sizes(maxWidth: 2000, traceSVG: { color: \\\"#639\\\" }) {\\n                ...GatsbyImageSharpSizes_tracedSVG\\n              }\\n            }\\n          }\\n        }\\n        fields {\\n          slug\\n        }\\n      }\\n    }\\n  }\\n`;\\n\")), mdx(YouTube, {\n    youTubeId: \"9S5GNtql02w\",\n    mdxType: \"YouTube\"\n  }), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"Additional resources:\")), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"this helped me for my own blog:\\n\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://juliangaramendy.dev/custom-open-graph-images-in-gatsby-blog/\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"https://juliangaramendy.dev/custom-open-graph-images-in-gatsby-blog/\"))), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"and the Gatsby docs:\\n\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.gatsbyjs.org/docs/working-with-images/\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"https://www.gatsbyjs.org/docs/working-with-images/\")))), mdx(\"h2\", {\n    \"id\": \"adding-an-seo-component-to-the-site\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#adding-an-seo-component-to-the-site\",\n    \"aria-label\": \"adding an seo component to the site permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Adding an SEO component to the site\"), mdx(YouTube, {\n    youTubeId: \"I9qQslUJknw\",\n    mdxType: \"YouTube\"\n  }), mdx(\"p\", null, \"There\\u2019s a Gatsby \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/gatsbyjs/gatsby/issues/14125\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"github PR on seo\"), \" with some \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/gatsbyjs/gatsby/pull/10780#issuecomment-451048608\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"great notes from Andrew\\nWelch\"), \" on SEO and a link to a presentation he did back in 2017.\"), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"Crafting Modern SEO with Andrew Welch:\")), mdx(\"p\", null, mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"vimeo: 246846978\")), mdx(\"p\", null, \"In the following comments of that PR, Gatsby\\u2019s \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/LekoArts\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"LekoArts\"), \" details \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/LekoArts/gatsby-starter-prismic/blob/master/src/components/SEO/SEO.jsx\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"his\\nown implementation\"), \" which I have implemented \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/spences10/react-seo-component\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"as a React component\"), \",\\nyou\\u2019re going to be configuring that now in this how-to.\"), mdx(\"p\", null, \"First up, install and configure, \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-plugin-react-helmet\"), \" this is\\nused for server rendering data added with React Helmet.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"yarn add gatsby-plugin-react-helmet\\n\")), mdx(\"p\", null, \"You\\u2019ll need to add the plugin to your \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-config.js\"), \". If you\\nhaven\\u2019t done so already now is a good time to also configure the\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-plugin-styled-components\"), \" as well.\"), mdx(\"h3\", {\n    \"id\": \"configure-seo-component-for-homepage\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h3\"\n  }, {\n    \"href\": \"#configure-seo-component-for-homepage\",\n    \"aria-label\": \"configure seo component for homepage permalink\",\n    \"className\": \"anchor-toc 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 SEO Component for Homepage\"), mdx(\"p\", null, \"To visualise the data you\\u2019re going to need to get into the SEO\\ncomponent use the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Dump\"), \" component to begin with to validate the data.\"), mdx(\"p\", null, \"The majority of the information needed for \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"src/pages/index.js\"), \" can be\\nfirst added to the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-config.js\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"siteMetadata\"), \" object then\\nqueried with the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"useSiteMetadata\"), \" hook. Some of the data added here\\ncan then be used in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"src/templates/blogPostTemplate.js\"), \", more on that\\nin the next section.\"), mdx(\"p\", null, \"For now add the following:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"const siteMetadata = {\\n  title: `The Localhost Blog`,\\n  description: `This is my coding blog where I write about my coding journey.`,\\n  image: `/default-site-image.jpg`,\\n  siteUrl: `https://thelocalhost.blog`,\\n  siteLanguage: `en-GB`,\\n  siteLocale: `en_gb`,\\n  twitterUsername: `@spences10`,\\n  authorName: `Scott Spence`,\\n}\\n\\nmodule.exports = {\\n  siteMetadata: siteMetadata,\\n  plugins: [\\n    ...\\n\")), mdx(\"p\", null, \"You don\\u2019t have to abstract out the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"siteMetadata\"), \" into it\\u2019s own\\ncomponent here, it\\u2019s only a suggestion on how to manage it.\"), mdx(\"p\", null, \"The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"image\"), \" is going to be the default image for your site, you should\\ncreate a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"static\"), \" folder at the root of the project and add in an\\nimage you want to be shown when the homepage of your site is shared on\\nsocial media.\"), mdx(\"p\", null, \"For \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"siteUrl\"), \" at this stage it doesn\\u2019t necessarily have to be valid,\\nadd a dummy url for now and you can change this later.\"), mdx(\"p\", null, \"The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"siteLanguage\"), \" is your language of choice for the site, take a\\nlook at \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.w3.org/International/articles/language-tags/\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"w3 language tags\"), \" for more info.\"), mdx(\"p\", null, \"Facebook OpenGraph is the only place the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"siteLocale\"), \" is used and it\\nis different from language tags.\"), mdx(\"p\", null, \"Add your \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"twitterUsername\"), \" and your \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"authorName\"), \".\"), mdx(\"p\", null, \"Update the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"useSiteMetadata\"), \" hook now to reflect the newly added\\nproperties:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"import { graphql, useStaticQuery } from 'gatsby';\\n\\nexport const useSiteMetadata = () => {\\n  const { site } = useStaticQuery(\\n    graphql`\\n      query SITE_METADATA_QUERY {\\n        site {\\n          siteMetadata {\\n            description\\n            title\\n            image\\n            siteUrl\\n            siteLanguage\\n            siteLocale\\n            twitterUsername\\n            authorName\\n          }\\n        }\\n      }\\n    `\\n  );\\n  return site.siteMetadata;\\n};\\n\")), mdx(\"p\", null, \"Begin with importing the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Dump\"), \" component in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"src/pages/index.js\"), \" then\\nplug in the props as they are detailed in the docs of the\\n\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/spences10/react-seo-component\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), mdx(\"inlineCode\", {\n    parentName: \"a\"\n  }, \"react-seo-component\")), \".\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"import Dump from '../components/Dump'\\nimport { useSiteMetadata } from '../hooks/useSiteMetadata'\\n\\nexport default ({ data }) => {\\n  const {\\n    description,\\n    title,\\n    image,\\n    siteUrl,\\n    siteLanguage,\\n    siteLocale,\\n    twitterUsername,\\n  } = useSiteMetadata()\\n  return (\\n    <Layout>\\n      <Dump\\n        title={title}\\n        description={description}\\n        image={`${siteUrl}${image}`}\\n        pathname={siteUrl}\\n        siteLanguage={siteLanguage}\\n        siteLocale={siteLocale}\\n        twitterUsername={twitterUsername}\\n      />\\n      <IndexWrapper>\\n        {data.allMdx.nodes.map(\\n          ...\\n\")), mdx(\"p\", null, \"Check that all the props are displaying valid values then you can swap\\nout the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Dump\"), \" component with the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"SEO\"), \" component.\"), mdx(\"p\", null, \"The complete \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"src/pages/index.js\"), \" should look like this now:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"import { graphql, Link } from 'gatsby';\\nimport Img from 'gatsby-image';\\nimport React from 'react';\\nimport SEO from 'react-seo-component';\\nimport styled from 'styled-components';\\nimport { Layout } from '../components/Layout';\\nimport { useSiteMetadata } from '../hooks/useSiteMetadata';\\n\\nconst IndexWrapper = styled.main``;\\n\\nconst PostWrapper = styled.div``;\\n\\nconst Image = styled(Img)`\\n  border-radius: 5px;\\n`;\\n\\nexport default ({ data }) => {\\n  const {\\n    description,\\n    title,\\n    image,\\n    siteUrl,\\n    siteLanguage,\\n    siteLocale,\\n    twitterUsername,\\n  } = useSiteMetadata();\\n  return (\\n    <Layout>\\n      <SEO\\n        title={title}\\n        description={description || `nothin\\u2019`}\\n        image={`${siteUrl}${image}`}\\n        pathname={siteUrl}\\n        siteLanguage={siteLanguage}\\n        siteLocale={siteLocale}\\n        twitterUsername={twitterUsername}\\n      />\\n      <IndexWrapper>\\n        {/* <Dump data={data}></Dump> */}\\n        {data.allMdx.nodes.map(\\n          ({ id, excerpt, frontmatter, fields }) => (\\n            <PostWrapper key={id}>\\n              <Link to={fields.slug}>\\n                {!!frontmatter.cover ? (\\n                  <Image\\n                    sizes={frontmatter.cover.childImageSharp.sizes}\\n                  />\\n                ) : null}\\n                <h1>{frontmatter.title}</h1>\\n                <p>{frontmatter.date}</p>\\n                <p>{excerpt}</p>\\n              </Link>\\n            </PostWrapper>\\n          )\\n        )}\\n      </IndexWrapper>\\n    </Layout>\\n  );\\n};\\n\\nexport const query = graphql`\\n  query SITE_INDEX_QUERY {\\n    allMdx(\\n      sort: { fields: [frontmatter___date], order: DESC }\\n      filter: { frontmatter: { published: { eq: true } } }\\n    ) {\\n      nodes {\\n        id\\n        excerpt(pruneLength: 250)\\n        frontmatter {\\n          title\\n          date(formatString: \\\"YYYY MMMM Do\\\")\\n          cover {\\n            publicURL\\n            childImageSharp {\\n              sizes(maxWidth: 2000, traceSVG: { color: \\\"#639\\\" }) {\\n                ...GatsbyImageSharpSizes_tracedSVG\\n              }\\n            }\\n          }\\n        }\\n        fields {\\n          slug\\n        }\\n      }\\n    }\\n  }\\n`;\\n\")), mdx(YouTube, {\n    youTubeId: \"O0jk9AqM_ls\",\n    mdxType: \"YouTube\"\n  }), mdx(\"h3\", {\n    \"id\": \"configure-seo-component-for-blog-posts\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h3\"\n  }, {\n    \"href\": \"#configure-seo-component-for-blog-posts\",\n    \"aria-label\": \"configure seo component for blog posts permalink\",\n    \"className\": \"anchor-toc 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 SEO Component for Blog Posts\"), mdx(\"p\", null, \"This will be the same approach as with the homepage, import the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Dump\"), \"\\ncomponent and validate the props before swapping out the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Dump\"), \"\\ncomponent with the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"SEO\"), \" component.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"import Dump from '../components/Dump'\\nimport { useSiteMetadata } from '../hooks/useSiteMetadata'\\n\\nexport default ({ data, pageContext }) => {\\n  const {\\n    image,\\n    siteUrl,\\n    siteLanguage,\\n    siteLocale,\\n    twitterUsername,\\n    authorName,\\n  } = useSiteMetadata()\\n  const { frontmatter, body, fields, excerpt } = data.mdx\\n  const { title, date, cover } = frontmatter\\n  const { previous, next } = pageContext\\n  return (\\n    <Layout>\\n      <Dump\\n        title={title}\\n        description={excerpt}\\n        image={\\n          cover === null\\n            ? `${siteUrl}${image}`\\n            : `${siteUrl}${cover.publicURL}`\\n        }\\n        pathname={`${siteUrl}${fields.slug}`}\\n        siteLanguage={siteLanguage}\\n        siteLocale={siteLocale}\\n        twitterUsername={twitterUsername}\\n        author={authorName}\\n        article={true}\\n        publishedDate={date}\\n        modifiedDate={new Date(Date.now()).toISOString()}\\n      />\\n      <h1>{frontmatter.title}</h1>\\n      ...\\n\")), mdx(\"p\", null, \"Add \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"fields.slug\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"excerpt\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"cover.publicURL\"), \" to the\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"PostsBySlug\"), \" query and destructure them from \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"data.mdx\"), \" and\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"frontmatter\"), \" respectively.\"), mdx(\"p\", null, \"For the image you\\u2019ll need to do some logic as to weather the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"cover\"), \"\\nexists and default to the default site image if it doesn\\u2019t.\"), mdx(\"p\", null, \"The complete \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"src/templates/blogPostTemplate.js\"), \" should look like this\\nnow:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"import { graphql, Link } from 'gatsby';\\nimport { MDXRenderer } from 'gatsby-plugin-mdx';\\nimport React from 'react';\\nimport SEO from 'react-seo-component';\\nimport { Layout } from '../components/Layout';\\nimport { useSiteMetadata } from '../hooks/useSiteMetadata';\\n\\nexport default ({ data, pageContext }) => {\\n  const {\\n    image,\\n    siteUrl,\\n    siteLanguage,\\n    siteLocale,\\n    twitterUsername,\\n    authorName,\\n  } = useSiteMetadata();\\n  const { frontmatter, body, fields, excerpt } = data.mdx;\\n  const { title, date, cover } = frontmatter;\\n  const { previous, next } = pageContext;\\n  return (\\n    <Layout>\\n      <SEO\\n        title={title}\\n        description={excerpt}\\n        image={\\n          cover === null\\n            ? `${siteUrl}${image}`\\n            : `${siteUrl}${cover.publicURL}`\\n        }\\n        pathname={`${siteUrl}${fields.slug}`}\\n        siteLanguage={siteLanguage}\\n        siteLocale={siteLocale}\\n        twitterUsername={twitterUsername}\\n        author={authorName}\\n        article={true}\\n        publishedDate={date}\\n        modifiedDate={new Date(Date.now()).toISOString()}\\n      />\\n      <h1>{frontmatter.title}</h1>\\n      <p>{frontmatter.date}</p>\\n      <MDXRenderer>{body}</MDXRenderer>\\n      {previous === false ? null : (\\n        <>\\n          {previous && (\\n            <Link to={previous.fields.slug}>\\n              <p>{previous.frontmatter.title}</p>\\n            </Link>\\n          )}\\n        </>\\n      )}\\n      {next === false ? null : (\\n        <>\\n          {next && (\\n            <Link to={next.fields.slug}>\\n              <p>{next.frontmatter.title}</p>\\n            </Link>\\n          )}\\n        </>\\n      )}\\n    </Layout>\\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        cover {\\n          publicURL\\n        }\\n      }\\n      body\\n      excerpt\\n      fields {\\n        slug\\n      }\\n    }\\n  }\\n`;\\n\")), mdx(YouTube, {\n    youTubeId: \"a2fcgYIQRIU\",\n    mdxType: \"YouTube\"\n  }), mdx(\"h3\", {\n    \"id\": \"build-site-and-validate-meta-tags\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h3\"\n  }, {\n    \"href\": \"#build-site-and-validate-meta-tags\",\n    \"aria-label\": \"build site and validate meta tags permalink\",\n    \"className\": \"anchor-toc 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 Site and Validate Meta Tags\"), mdx(\"p\", null, \"Add in the build script to \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"package.json\"), \" and also a script for\\nserving the built site locally.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-json\"\n  }), \"\\\"scripts\\\": {\\n  \\\"dev\\\": \\\"gatsby develop -p 9988 -o\\\",\\n  \\\"build\\\": \\\"gatsby build\\\",\\n  \\\"serve\\\": \\\"gatsby serve -p 9500 -o\\\"\\n},\\n\")), mdx(\"p\", null, \"Now it\\u2019s time to run:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"yarn build && yarn serve\\n\")), mdx(\"p\", null, \"This will build the site and open a browser tab so you can see the\\nsite as it will appear when it is on the internet. Validate meta tags\\nhave been added to the build by selecting \\u201CView page source\\u201D (Crtl+u\\nin Windows and Linux) on the page and do a Ctrl+f to find them.\"), mdx(YouTube, {\n    youTubeId: \"c6bB9ddAgjc\",\n    mdxType: \"YouTube\"\n  }), mdx(\"h2\", {\n    \"id\": \"adding-the-project-to-github\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#adding-the-project-to-github\",\n    \"aria-label\": \"adding the project to github permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Adding the Project to GitHub\"), mdx(\"p\", null, \"Add your code to GitHub by either selecting the plus (+) icon next to\\nyour avatar on GitHub or by going to directly to\\n\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/new\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"https://github.com/new\")), mdx(\"p\", null, \"Name your repository and click create repository, then you will be\\ngiven the instructions to link your local code to the repository you\\ncreated via the command line.\"), mdx(\"p\", null, \"Depending on how you authenticate with GitHub will depend on what the\\ncommand looks like.\"), mdx(\"p\", null, \"Some good resources for authenticating with GitHub via SSH are \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://egghead.io/lessons/javascript-how-to-authenticate-with-github-using-ssh\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"Kent\\nDodds Egghead.io video\"), \" and also a how-to \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.cheatsheets.xyz/git/#how-to-authenticate-with-github-using-ssh\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"on CheatSheets.xyz\"), \".\"), mdx(YouTube, {\n    youTubeId: \"r2eiJ8E_YT0\",\n    mdxType: \"YouTube\"\n  }), mdx(\"h2\", {\n    \"id\": \"deploy-to-netlify\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#deploy-to-netlify\",\n    \"aria-label\": \"deploy to netlify permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Deploy to Netlify\"), mdx(\"p\", null, \"To deploy your site to Netlify, if you haven\\u2019t done so already you\\u2019ll\\nneed to add the GitHub integration to your GitHub profile. If you got\\nto \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://app.netlify.com\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"app.netlify.com\"), \" the wizard will walk you\\nthrough the process.\"), mdx(\"p\", null, \"From here you can add your built site\\u2019s \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"public\"), \" folder, drag \\u2018n drop\\nstyle directly to the Netlify global CDNs.\"), mdx(\"p\", null, \"You, however are going to load your site via the Netlify CLI! In your\\nterminal, if you haven\\u2019t already got the CLI installed, run:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"yarn global add netlify-cli\\n\")), mdx(\"p\", null, \"Then once the CLI is installed:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"# authenticate via the CLI\\nnetlify login\\n# initialise the site\\nnetlify init\\n\")), mdx(\"p\", null, \"Enter the details for your team, the site name is optional, the build\\ncommand will be \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"yarn build\"), \" and directory to deploy is \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"public\"), \".\"), mdx(\"p\", null, \"You will be prompted to commit the changes and push them to GitHub\\n(with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"git push\"), \"), once you have done that your site will be published\\nand ready for all to see!\"), mdx(YouTube, {\n    youTubeId: \"voWeHvIGB0g\",\n    mdxType: \"YouTube\"\n  }), mdx(\"h2\", {\n    \"id\": \"validate-metadata-with-heymeta\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h2\"\n  }, {\n    \"href\": \"#validate-metadata-with-heymeta\",\n    \"aria-label\": \"validate metadata with heymeta permalink\",\n    \"className\": \"anchor-toc 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  })))), \"Validate Metadata with Heymeta\"), mdx(\"p\", null, \"Last up is validating the metadata for the OpenGraph fields, to do\\nthat you\\u2019ll need to make sure that the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"siteUrl\"), \" reflecting what you\\nhave in your Netlify dashboard.\"), mdx(\"p\", null, \"If you needed to change the url you\\u2019ll need to commit and push the\\nchanges to GitHub again.\"), mdx(\"p\", null, \"Once your site is built with a valid url you can then test the\\nhomepage and a blog page for the correct meta tags with\\n\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"http://heymeta.com/\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"heymeta.com\"), \".\"), mdx(YouTube, {\n    youTubeId: \"JH1AVanYhwo\",\n    mdxType: \"YouTube\"\n  }), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"OpenGraph checking tools:\")), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"https://www.heymeta.com/\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"heymeta\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"https://opengraphcheck.com/\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"opengraphcheck\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"https://cards-dev.twitter.com/validator\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"twitter validator\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"https://developers.facebook.com/tools/debug/sharing\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"facebook sharing\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"https://www.linkedin.com/post-inspector/\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"linkedin inspector/\"))), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"Additional resources:\")), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"https://css-tricks.com/essential-meta-tags-social-media/\",\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"The Essential Meta Tags for Social Media\"))), 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-toc 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, \"That\\u2019s all folks! If there is anything I have missed, or if there is a\\nbetter way to do something then please let me know.\"), 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.\"));\n}\n;\nMDXContent.isMDXComponent = true;","excerpt":"I have been a Gatsby user since around  v0 May 2017 , at that time was\nusing a template called  Lumen  and it was just what I needed at the…","tableOfContents":{"items":[{"url":"#what-does-that-mean","title":"What does that mean?"},{"url":"#what-youre-going-to-build","title":"What you're going to build"},{"url":"#whos-this-how-to-for","title":"Who's this how-to for?"},{"url":"#requirements","title":"Requirements"},{"url":"#hello-world","title":"Hello World","items":[{"url":"#basic-hello-world","title":"basic hello world"}]},{"url":"#add-content","title":"Add content"},{"url":"#gatsby-config-api","title":"Gatsby config API"},{"url":"#plugins","title":"Plugins","items":[{"url":"#gatsby-source-filesystem","title":"Gatsby source filesystem"},{"url":"#gatsby-plugin-mdx","title":"Gatsby plugin MDX"}]},{"url":"#query-data-from-graphql","title":"Query data from GraphQL"},{"url":"#site-metadata","title":"Site Metadata"},{"url":"#site-metadata-hook","title":"Site metadata hook"},{"url":"#styling","title":"Styling","items":[{"url":"#install-styled-components","title":"install styled-components"},{"url":"#configure","title":"Configure"}]},{"url":"#layout","title":"Layout"},{"url":"#index-page-posts-query","title":"Index page posts query"},{"url":"#slugs-and-paths","title":"Slugs and Paths"},{"url":"#link-paths","title":"Link Paths"},{"url":"#adding-a-blog-post-template","title":"Adding a Blog Post Template"},{"url":"#build-out-blog-post-template","title":"Build out Blog Post Template"},{"url":"#previous-and-next","title":"Previous and Next"},{"url":"#code-blocks","title":"Code Blocks","items":[{"url":"#copy-code-to-clipboard","title":"Copy code to clipboard"}]},{"url":"#react-live","title":"React live"},{"url":"#cover-image","title":"Cover Image"},{"url":"#adding-an-seo-component-to-the-site","title":"Adding an SEO component to the site","items":[{"url":"#configure-seo-component-for-homepage","title":"Configure SEO Component for Homepage"},{"url":"#configure-seo-component-for-blog-posts","title":"Configure SEO Component for Blog Posts"},{"url":"#build-site-and-validate-meta-tags","title":"Build Site and Validate Meta Tags"}]},{"url":"#adding-the-project-to-github","title":"Adding the Project to GitHub"},{"url":"#deploy-to-netlify","title":"Deploy to Netlify"},{"url":"#validate-metadata-with-heymeta","title":"Validate Metadata with Heymeta"},{"url":"#thanks-for-reading-","title":"Thanks for reading 🙏"}]},"timeToRead":18,"fields":{"slug":"/2019/10/31/build-an-mdx-blog/","editLink":"https://github.com/spences10/thelocalhost.blog/edit/authoring/posts/2019/10/31/build-an-mdx-blog/index.mdx"}}},"pageContext":{"slug":"/2019/10/31/build-an-mdx-blog/","previous":{"id":"455088b1-8655-5b0b-90bb-8a8f5f4afbc3","excerpt":"I've been wanting to go to a JAMstack conf since the first one was\nscheduled for October 2018. This year when it was announced there\nwould be one in London I was super excited to get the opportunity to\ngo. The conference was across two days with the…","frontmatter":{"title":"JAMstack_conf London 2019","date":"2019-07-19T00:00:00.000Z"},"fields":{"slug":"/2019/07/19/jamstack-london-2019/"}},"next":{"id":"1c70f7fc-8e60-5d91-ab35-59ca9b4c09fe","excerpt":"React Advanced London going deep! Here's my recollection of my attendance at React Advanced London 2019\nsupported with videos from the event. Ken Wheeler - React Performance Ken's keynote didn't disappoint! Ken talks about how performance fixes\naren…","frontmatter":{"title":"React Advanced - London 2019","date":"2019-12-31T00:00:00.000Z"},"fields":{"slug":"/2019/11/06/react-advanced-london-2019/"}}}}}