{"componentChunkName":"component---src-templates-blog-post-js","path":"/blog/using-html-modules/","result":{"data":{"site":{"siteMetadata":{"title":"The Official MailPace Blog","author":"Paul, founder of MailPace"}},"mdx":{"id":"9b8f671f-d474-580d-a8c6-b070df40e7b1","excerpt":"Our landing page  https://mailpace.com  is a static site that consists of a simple set of HTML pages, with a tiny sprinkling of JavaScript here and there. We…","body":"var _excluded = [\"components\"];\n\nfunction _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/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"Modularizing a static website with HTML Modules and PostHTML\",\n  \"date\": \"2021-06-16T16:00:03.284Z\",\n  \"description\": \"How to enhance a static set of HTML pages with HTML Modules and PostHTML\"\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, _excluded);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"Our landing page \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://mailpace.com\"\n  }, \"https://mailpace.com\"), \" is a static site that consists of a simple set of HTML pages, with a tiny sprinkling of JavaScript here and there. We started with a single HTML page and for links like our Privacy Policy and Terms of Service, we copied and pasted everything into a new file for each page.\"), mdx(\"p\", null, \"This was fine for a little while, but eventually it became annoying to keep updating each html file, so we wanted to add a way to modularize our pages. The idea is to keep the footer, header, nav bar and other components the same across the site, in a \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://en.wikipedia.org/wiki/Don%27t_repeat_yourself\"\n  }, \"DRY\"), \" way.\"), mdx(\"p\", null, \"Rather than bring in a new static site framework, we wanted something we could easily add to our existing NPM scripts that we already have for including TailwindCSS and hosting a local dev server.\"), mdx(\"h2\", null, \"Enter HTML Modules & HTML Imports\"), mdx(\"p\", null, \"HTML Modules & Imports are similar specifications that allow splitting up web pages into different HTML components to improve reusability. There are some competing opinions on how these should work and Chromium already has a implementation called HTML Imports. \"), mdx(\"p\", null, \"The W3C have a great explainer here: \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/WICG/webcomponents/blob/gh-pages/proposals/html-modules-explainer.md\"\n  }, \"https://github.com/WICG/webcomponents/blob/gh-pages/proposals/html-modules-explainer.md\"), \" - but essentially it\\u2019s a standard that should work well in the same way ES6 modules work well in JavaScript. The alternative to HTML Modules/Imports is to use an HTML templating language - there\\u2019s lots to choose from, but we felt they were more geared towards injecting data into HTML files, than really modularizing things.\"), mdx(\"p\", null, \"The problem is that HTML Modules / Imports isn\\u2019t finalised & agreed (and we probably don\\u2019t need all that ES6 jazz anyway), so how do we add this modular approach to our website?\"), mdx(\"h2\", null, \"How to (sort of) use HTML Modules today on the Server\"), mdx(\"p\", null, \"Although the spec isn\\u2019t complete there is an implementation of PostHTML (an HTML post-processor, similar to PostCSS) which covers modules, called \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/posthtml/posthtml-modules\"\n  }, \"PostHTML-Modules\"), \".\"), mdx(\"p\", null, \"This library allows you to Import and process HTML Modules with PostHTML by adding a processing build step to your application pipeline. It\\u2019s not quite what the W3C has in mind, but looks great for our use case.\"), mdx(\"h2\", null, \"Structuring our pages into HTML Modules\"), mdx(\"p\", null, \"To setup our site we change our pages into a simple HTML structure that combines our standard Layout with our Content. For each page we have a file that looks like this:\"), mdx(\"pre\", {\n    \"className\": \"grvsc-container default-dark\",\n    \"data-language\": \"html\",\n    \"data-index\": \"0\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"grvsc-code\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"<\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"module\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \" \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk12\"\n  }, \"href\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"=\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \"\\\"/components/layout.html\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"    \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"<\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"module\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \" \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk12\"\n  }, \"href\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"=\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \"\\\"/content/content.html\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"></\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"module\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"</\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"module\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\")))), mdx(\"p\", null, \"Where layout.html contains our basic layout and pulls in a Head section, Nav bar and Footer (defined in their own html files).\"), mdx(\"pre\", {\n    \"className\": \"grvsc-container default-dark\",\n    \"data-language\": \"html\",\n    \"data-index\": \"1\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"grvsc-code\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"<!\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"DOCTYPE\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \" \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk12\"\n  }, \"html\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"<\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"html\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \" \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk12\"\n  }, \"lang\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"=\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \"\\\"en\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"\\t\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"<\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"module\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \" \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk12\"\n  }, \"href\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"=\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \"\\\"/components/head.html\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"></\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"module\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"    \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"<\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"body\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"        \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"<\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"module\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \" \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk12\"\n  }, \"href\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"=\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \"\\\"/components/nav.html\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"></\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"module\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"        \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"<\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"content\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"></\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"content\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"        \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"<\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"module\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \" \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk12\"\n  }, \"href\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"=\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \"\\\"/components/footer.html\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"></\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"module\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"    \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"</\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"body\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"</\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"html\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\")))), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"The important tag here is \", mdx(\"inlineCode\", {\n    parentName: \"strong\"\n  }, \"<content></content>\"), \" - this will place any code from inside the parent \", mdx(\"module\", null), \" tag into this section when the page is rendered, in this case our content.html file.\")), mdx(\"p\", null, \"The content page can contain any HTML, such as the Landing Page sections, Privacy Policy, Terms of Service etc.\"), mdx(\"p\", null, \"The end result that our compilation step will spit out is a combination of all of these individual modules rendered together, each in their own single page:\"), mdx(\"pre\", {\n    \"className\": \"grvsc-container default-dark\",\n    \"data-language\": \"html\",\n    \"data-index\": \"2\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"grvsc-code\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"<!\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"DOCTYPE\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \" \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk12\"\n  }, \"html\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"<\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"html\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \" \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk12\"\n  }, \"lang\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"=\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \"\\\"en\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"    \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"<\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"head\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"Head\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"</\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"head\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"    \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"<\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"body\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"        \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"<\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"nav\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"Nav here\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"</\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"nav\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"        \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"<\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"div\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"Custom page content here\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"</\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"div\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"        \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"<\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"div\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"Footer here\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"</\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"div\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"    \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"</\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"body\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \"</\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"html\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk17\"\n  }, \">\")))), mdx(\"h2\", null, \"Compiling the pages using NPM\"), mdx(\"p\", null, \"We already use NPM to include TailwindCSS and host a simple development server with live reloading, so we\\u2019ll add compilation of the HTML modules to our build step using PostHTML.\"), mdx(\"p\", null, \"Install PostHTML Modules and onchange (onchange is for watching and rebuilding the pages when developing):\"), mdx(\"p\", null, \" \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"npm i -D posthtml-modules onchange\")), mdx(\"p\", null, \"Then create \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"posthtml.json\"), \" in the root of our project:\"), mdx(\"pre\", {\n    \"className\": \"grvsc-container default-dark\",\n    \"data-language\": \"json\",\n    \"data-index\": \"3\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"grvsc-code\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"{\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"  \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk12\"\n  }, \"\\\"input\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \": \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \"\\\"html/*.html\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \",\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"  \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk12\"\n  }, \"\\\"output\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \": \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \"\\\"public\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \",\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"  \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk12\"\n  }, \"\\\"plugins\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \": {\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"      \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk12\"\n  }, \"\\\"posthtml-modules\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \": {\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"          \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk12\"\n  }, \"\\\"root\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \": \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \"\\\"./html\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \",\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"          \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk12\"\n  }, \"\\\"initial\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \": \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk4\"\n  }, \"true\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"      }\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"  }\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"}\")))), mdx(\"p\", null, \"Update our build/watch npm scripts to include posthtml inside \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"package.json\"), \":\"), mdx(\"pre\", {\n    \"className\": \"grvsc-container default-dark\",\n    \"data-language\": \"json\",\n    \"data-index\": \"4\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"grvsc-code\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"  \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \"\\\"scripts\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \": {\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"    \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk12\"\n  }, \"\\\"serve\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \": \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \"\\\"cross-env NODE_ENV=development concurrently \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk6\"\n  }, \"\\\\\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \"npm run watch:css\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk6\"\n  }, \"\\\\\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \" \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk6\"\n  }, \"\\\\\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \"npm run watch:html\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk6\"\n  }, \"\\\\\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \" \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk6\"\n  }, \"\\\\\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \"live-server ./public\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk6\"\n  }, \"\\\\\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \"\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \",\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"    \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk12\"\n  }, \"\\\"development\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \": \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \"\\\"cross-env NODE_ENV=development npm run build:css && npm run build:html\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \",\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"    \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk12\"\n  }, \"\\\"production\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \": \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \"\\\"cross-env NODE_ENV=production npm run build:css && npm run build:html\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \",\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"    \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk12\"\n  }, \"\\\"build:html\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \": \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \"\\\"posthtml -c posthtml.json\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \",\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"    \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk12\"\n  }, \"\\\"watch:html\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \": \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \"\\\"npm run build:html & onchange \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk6\"\n  }, \"\\\\\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \"html/**/*.html\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk6\"\n  }, \"\\\\\\\"\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk8\"\n  }, \" -- npm run build:html\\\"\")), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"grvsc-line\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mtk1\"\n  }, \"  },\")))), mdx(\"p\", null, \"And that\\u2019s it! When you run \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"npm run build:html\"), \", your pages will be compiled to \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"/public\"), \" and from there it\\u2019s super easy to host on any static provider.\"), mdx(\"style\", {\n    \"className\": \"grvsc-styles\"\n  }, \"\\n  .grvsc-container {\\n    overflow: auto;\\n    -webkit-overflow-scrolling: touch;\\n    padding-top: 1rem;\\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\\n    padding-bottom: 1rem;\\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\\n    border-radius: 8px;\\n    border-radius: var(--grvsc-border-radius, 8px);\\n    font-feature-settings: normal;\\n  }\\n  \\n  .grvsc-code {\\n    display: inline-block;\\n    min-width: 100%;\\n  }\\n  \\n  .grvsc-line {\\n    display: inline-block;\\n    box-sizing: border-box;\\n    width: 100%;\\n    padding-left: 1.5rem;\\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\\n    padding-right: 1.5rem;\\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\\n  }\\n  \\n  .grvsc-line-highlighted {\\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\\n  }\\n  \\n  .default-dark {\\n    background-color: #1E1E1E;\\n    color: #D4D4D4;\\n  }\\n  .default-dark .mtk17 { color: #808080; }\\n  .default-dark .mtk4 { color: #569CD6; }\\n  .default-dark .mtk1 { color: #D4D4D4; }\\n  .default-dark .mtk12 { color: #9CDCFE; }\\n  .default-dark .mtk8 { color: #CE9178; }\\n  .default-dark .mtk6 { color: #D7BA7D; }\\n\"));\n}\n;\nMDXContent.isMDXComponent = true;","frontmatter":{"title":"Modularizing a static website with HTML Modules and PostHTML","date":"June 16, 2021","description":"How to enhance a static set of HTML pages with HTML Modules and PostHTML"}}},"pageContext":{"slug":"/using-html-modules/","previous":{"fields":{"slug":"/send-transactional-emails-with-php/"},"frontmatter":{"title":"Send transactional emails using PHP"}},"next":{"fields":{"slug":"/free-transactional-email-templates/"},"frontmatter":{"title":"Free Transactional Email Templates"}}}},"staticQueryHashes":["1956864136","63159454"]}