DEV Community

Cover image for On the sixth day of Enhancing: Head component
Simon MacDonald for Begin

Posted on • Originally published at blog.begin.com

3

On the sixth day of Enhancing: Head component

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>
  `
}
Enter fullscreen mode Exit fullscreen mode

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>
  `
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

Finally, I’ll add a <link rel=”me”> tag to the head for my Mastodon account

<link rel="me" href="https://mastodon.online/@macdonst">
Enter fullscreen mode Exit fullscreen mode

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>
  `
}
Enter fullscreen mode Exit fullscreen mode

Sentry blog image

How to reduce TTFB

In the past few years in the web dev world, we’ve seen a significant push towards rendering our websites on the server. Doing so is better for SEO and performs better on low-powered devices, but one thing we had to sacrifice is TTFB.

In this article, we’ll see how we can identify what makes our TTFB high so we can fix it.

Read more

Top comments (0)

Image of Timescale

Timescale – the developer's data platform for modern apps, built on PostgreSQL

Timescale Cloud is PostgreSQL optimized for speed, scale, and performance. Over 3 million IoT, AI, crypto, and dev tool apps are powered by Timescale. Try it free today! No credit card required.

Try free