On the sixth day of Enhancing: Head component

Simon MacDonald’s avatar

by Simon MacDonald
@macdonst
@macdonst@mastodon.online
on

six geese 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>
  `
}