On the sixth day of Enhancing: Head component
by Simon MacDonald
@macdonst
@macdonst@mastodon.online
on
Original photo by Nick Fewings on Unsplash
Welcome back. Things are looking much nicer after applying some styles yesterday. Let’s switch gears and add a function to create the <head>
element for all pages in our project. In an Enhance app, this can be done in the app/head.mjs
file.
Here’s the baseline functionality that is the default in an Enhance project:
import { getStyles } from '@enhance/arc-plugin-styles'
export default function Head() {
const styles = process.env.ARC_LOCAL
? getStyles.linkTag()
: getStyles.styleTag()
return `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
${ styles }
<link rel="icon" href="/_public/favicon.svg">
</head>
`
}
We’ll re-use much of this in a custom app/head.mjs
file as we add more functionality.
import { getStyles } from '@enhance/arc-plugin-styles'
export default function Head(state) {
const { store, status, req, error } = state
const { path } = req
const title = `My app — ${path}`
return `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>${ title }</title>
${ getStyles.styleTag() }
<link rel="icon" href="/_public/favicon.svg">
</head>
`
}
Here I’ve added the state argument and started destructuring its parts to create the page’s <title>
from the current path.
We have access to other bits of state like the server’s return status code, any errors, and the entire store object returned from an API route middleware. So we can tailor our document to each request.
Additionally, I’ve opted to inline the style tag from arc-plugin-styles.
As the logic in this file grows, it is encouraged to break out functionality into their own importable scripts. See how app/templates/ are used in the Enhance.dev docs.
While we’re here, let’s apply some global styles by adding a simple <style>
tag:
<style>
body {
margin: 0 auto;
max-width: 80rem;
}
</style>
Finally, I’ll add a <link rel=”me”>
tag to the head for my Mastodon account
<link rel="me" href="https://mastodon.online/@macdonst">
This will verify to other sites and services that this mastodon.online account belongs to the same owner of this Enhance project’s domain.
And the full, updated app/head.mjs
file:
import { getStyles } from '@enhance/arc-plugin-styles'
export default function Head({ req }) {
const { path } = req
const title = `My app — ${path}`
return `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>${title}</title>
${getStyles.styleTag()}
<link rel="me" href="https://mastodon.online/@macdonst">
<link rel="icon" href="/_public/favicon.svg">
<style>
body {
margin: 0 auto;
max-width: 80rem;
}
</style>
</head>
`
}