Enhance your Astro builds: modify HTML files post-build
As a freelance web developer with expertise in optimizing website performance, I specialize in creating lightning-fast and SEO-optimized websites.
Freelance web developer
As Astro developers, we're always looking for ways to optimize our websites and improve performance. In this blog post, I'll walk you through a script that can modify your Astro-generated HTML files after the build process. This script adds IDs to heading tags and minifies the HTML, making your website faster and more accessible. Let's dive in!
Contents
Getting started
Before you can begin, ensure that you have the following prerequisites installed on your system:
Installing dependencies
Our script relies on three dependencies: 'globby', 'html-minifier', and 'jsdom'. Install them by running the following command:
npm install globby html-minifier jsdom
The process-html.mjs
script
Create a new file named process-html.mjs
in your Astro project's root directory. The code below is tailored for static deployments on Vercel. If you're using a different output folder, modify the path
variable accordingly.
import fs from 'node:fs/promises'
import { globby } from 'globby'
import { minify } from 'html-minifier'
import { JSDOM } from 'jsdom'
// Get all HTML files from the output directory
const path = './.vercel/output/static'
const files = await globby(`${path}/**/*.html`)
await Promise.all(
files.map(async (file) => {
console.log('Processing file:', file)
let html = await fs.readFile(file, 'utf-8')
// Add IDs to h2, h3, and h4 tags
const dom = new JSDOM(html)
const headings = dom.window.document.querySelectorAll('h2, h3, h4')
for (let i = 0; i < headings.length; i++) {
const heading = headings[i]
const text = heading.textContent
const id = text
.trim()
.replace(/[\s.,?:]+/g, '-')
.replace(/-+$/, '')
.toLowerCase()
heading.setAttribute('id', id)
}
html = dom.serialize()
// Minify the HTML
html = minify(html, {
removeComments: true,
preserveLineBreaks: true,
collapseWhitespace: true
})
await fs.writeFile(file, html)
})
)
Updating package.json
Update your package.json
file to execute the script after the build process. Add && node process-html.mjs
after, astro build
as shown in the example below.
{
"name": "astro-process-html",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro build && node process-html.mjs",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"astro": "~2.1.3",
"@astrojs/vercel": "~3.2.1",
"globby": "~13.1.3",
"html-minifier": "~4.0.0",
"jsdom": "~21.0.0"
}
}
Conclusion
Following these steps, you've successfully created a script that modifies your Astro-generated HTML files after the build process. This enhancement will add IDs to heading tags and minify your HTML, improving the performance and accessibility of your website. Don't hesitate to customize the script further to meet your specific needs, and check out the html-minifier reference guide for additional configuration options. Feel free to reach out if you have any questions or need further assistance! Happy coding! 😉
Frequently asked questions
FAQ
Let's dive deeper into some frequently asked questions.
Can I use this script with other static site generators?
While this script is tailored for Astro, you can adapt it to work with other static site generators by modifying the path
variable to match the output directory of your preferred SSG.
Can I add more tasks to this script?
Absolutely! You can expand the script's functionality to include tasks such as adding critical CSS or optimizing images. Just install any necessary dependencies and integrate them into the script.
What if I want to add IDs to different HTML elements?
You can modify the querySelectorAll
method within the script to target different elements. For example, change 'h2, h3, h4'
to 'h1, h2, h3'
and target <h1>
, <h2>
, and <h3>
elements instead.
Can I exclude certain files or directories from processing?
Yes, you can do this by adjusting the globby
pattern. Refer to the globby documentation for more information on creating custom patterns.