Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: custom fonts with preloading #209

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"@astrojs/check": "^0.9.3",
"@astrojs/cloudflare": "^12.0.0-beta.0",
"@astrojs/sitemap": "^3.1.6",
"@fontsource/archivo": "^5.1.0",
"@nanostores/persistent": "^0.10.1",
"@rollup/plugin-graphql": "^2.0.3",
"accept-language-parser": "^1.5.0",
Expand Down
9 changes: 9 additions & 0 deletions src/assets/fonts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import '@fontsource/archivo/400.css';
jbmoelker marked this conversation as resolved.
Show resolved Hide resolved
import '@fontsource/archivo/600.css';

import archivo400url from '@fontsource/archivo/files/archivo-latin-400-normal.woff2?url';
import archivo600url from '@fontsource/archivo/files/archivo-latin-600-normal.woff2?url';

export const fontFamilyArchivo = 'Archivo, sans-serif';

export const woff2urls = [archivo400url, archivo600url];
19 changes: 19 additions & 0 deletions src/components/PerfHead/PerfHead.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
jbmoelker marked this conversation as resolved.
Show resolved Hide resolved
import { datocmsAssetsOrigin, datocmsGraphqlOrigin } from '@lib/datocms';
import { woff2urls } from '@assets/fonts';

const preConnectOrigins = [datocmsAssetsOrigin, datocmsGraphqlOrigin];
---

{preConnectOrigins.map((origin) => <link rel="preconnect" href={origin} />)}
{
woff2urls.map((url) => (
<link
rel="preload"
as="font"
type="font/woff2"
href={url}
crossorigin="anonymous"
/>
))
}
8 changes: 8 additions & 0 deletions src/components/PerfHead/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Perf Head

**Loading instructions for resources on criticial rendering path to improve page loading performance.**

## Relevant links

- [web.dev: Establish network connections early to improve perceived page speed](https://web.dev/articles/preconnect-and-dns-prefetch)
- [web.dev: Preload web fonts to improve loading speed](https://web.dev/articles/codelab-preload-web-fonts)
67 changes: 44 additions & 23 deletions src/layouts/Default.astro
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
---
import type { DefaultLayoutQuery, Site, SiteLocale, Tag } from '@lib/datocms/types';
import type {
DefaultLayoutQuery,
Site,
SiteLocale,
Tag,
} from '@lib/datocms/types';
import { datocmsRequest } from '@lib/datocms';
import { defaultLocale, t } from '@lib/i18n';
import { getHomeHref } from '@lib/routing';
Expand All @@ -11,10 +16,12 @@ import Breadcrumbs from '@components/Breadcrumbs/Breadcrumbs.astro';
import type { Breadcrumb } from '@components/Breadcrumbs';
import IconSprite from '@components/Icon/IconSprite.astro';
import LocaleSelector from '@components/LocaleSelector/LocaleSelector.astro';
import PerfHead from '@components/PerfHead/PerfHead.astro';
import PreviewModeProvider from '@components/PreviewMode/PreviewModeProvider.astro';
import StructuredData from '@components/StructuredData/StructuredData.astro';
import SeoHead from '@components/SeoHead.astro';
import SkipLink from '@components/SkipLink/SkipLink.astro';
import { fontFamilyArchivo } from '@assets/fonts';
import '@assets/a11y.css';

interface Props {
Expand All @@ -24,65 +31,79 @@ interface Props {
}

const { locale = defaultLocale } = Astro.params as { locale?: SiteLocale };
const data = await datocmsRequest<DefaultLayoutQuery>({ query, variables: { locale } }) as { site: Site };
const data = (await datocmsRequest<DefaultLayoutQuery>({
query,
variables: { locale },
})) as { site: Site };
const { breadcrumbs = [], pageUrls, seoMetaTags } = Astro.props;
const mainContentId = 'content';
---

<!DOCTYPE html>
<html lang={ locale }>
<!doctype html>
<html lang={locale}>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<StructuredData />
<PerfHead />
<SeoHead
pageUrls={ pageUrls }
pageUrls={pageUrls}
tags={[...data.site.faviconMetaTags, ...seoMetaTags]}
/>
<StructuredData />
</head>
<body>
<PreviewModeProvider>
<SkipLink targetId={ mainContentId } />
<header { ...datocmsNoIndex }>
{ /* accessible home link, inspired by https://www.gov.uk/; with Microformats rel */ }
<a rel="home" href={ getHomeHref() } aria-label={ t('go_to_home_page', { siteName }) }>[Logo]</a>
<SkipLink targetId={mainContentId} />
<header {...datocmsNoIndex}>
{
/* accessible home link, inspired by https://www.gov.uk/; with Microformats rel */
}
<a
rel="home"
href={getHomeHref()}
aria-label={t('go_to_home_page', { siteName })}>[Logo]</a
>
<div>
<LocaleSelector pageUrls={ pageUrls } />
<a rel="search" href={ getSearchPathname(locale) }>{ t('search') }</a>
<LocaleSelector pageUrls={pageUrls} />
<a rel="search" href={getSearchPathname(locale)}>{t('search')}</a>
</div>
</header>
{ (breadcrumbs.length > 0) && (
<Breadcrumbs items={breadcrumbs} />
) }
{ /* main element requires tabindex to be focusable, see SkipLink/README.md */ }
<main id={ mainContentId } tabindex="-1">
{breadcrumbs.length > 0 && <Breadcrumbs items={breadcrumbs} />}
{
/* main element requires tabindex to be focusable, see SkipLink/README.md */
}
<main id={mainContentId} tabindex="-1">
<slot />
</main>
<footer { ...datocmsNoIndex }>
<footer {...datocmsNoIndex}>
<p>Footer</p>
</footer>
</PreviewModeProvider>
<IconSprite />
</body>
</html>

<style is:global>
<style is:global define:vars={{ fontFamilyArchivo }}>
/* very basic reset */
*, *::before, *::after {
*,
*::before,
*::after {
box-sizing: border-box;
}
html, body {
html,
body {
margin: 0;
padding: 0;
font-family: sans-serif;
font-family: var(--fontFamilyArchivo);
}
figure {
margin: 0;
}
</style>
<style>
/* Sticky footer. @see https://css-tricks.com/a-clever-sticky-footer-technique/ */
html, body {
html,
body {
height: 100%;
}
footer {
Expand Down
5 changes: 4 additions & 1 deletion src/lib/datocms/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import { DATOCMS_READONLY_API_TOKEN, HEAD_START_PREVIEW } from 'astro:env/server

const wait = (milliSeconds: number) => new Promise((resolve) => setTimeout(resolve, milliSeconds));

export const datocmsAssetsOrigin = 'https://www.datocms-assets.com/';
export const datocmsGraphqlOrigin = 'https://graphql.datocms.com/';

type DatocmsRequest = {
query: DocumentNode;
variables?: { [key: string]: string };
Expand All @@ -29,7 +32,7 @@ export const datocmsRequest = async <T>({ query, variables = {}, retryCount = 1
headers.append('X-Include-Drafts', 'true');
}

const response = await fetch('https://graphql.datocms.com/', {
const response = await fetch(datocmsGraphqlOrigin, {
method: 'post',
headers,
body: JSON.stringify({ query: print(query), variables }),
Expand Down
Loading