Despite the Government of Canada having a web presence for 30 years now, one of the weirdly persistent problems when building government web applications is how to deal with logos.
The problem is with what is known as “signature blocks”; the combination of flag plus department name (or just “Government of Canada”) that you’ll find at the top of every website.
At first glance, it’s a solved problem, but if you look closely at one of these largely textual logos you’ll notice that it’s a picture: The logos all include an image of text rather than text itself, along with a flag.
This is visible everywhere from the new Design System, to Canada.ca itself, all recycling the same problematic logos.
Given that this is a well known accessibility problem, and doesn’t respect my choice of language (on the web I can specify my language, but the logo images always include both), and doesn’t work for mobile devices (including both languages isn’t good on a small screen)… it’s an odd pattern to see across every government site.
Why would anyone make a picture of text?
Because in 1970, the Federal Identity Program selected Helvetica as the official font of the Government of Canada. An eminently reasonable decision for the centralized team and world of print that existed at the time, this has caused major problems for generations of departmental web developers who then realize that as a commercial font Helvetica can’t legally be used without a license. Given the governments broken procurement process, and the insanity of trying to navigate it for each web application people have opted to simply take a picture of the text instead.
This decision, combined with the fact that the only examples of logos all have both languages because of the FIPs origins in signage and stationary (where users can’t express which language they want to see) have created the bizarre mess we have currently.
Helvetica compatible fonts to the rescue
There have been a few “Helvetica clones” published over the years that allow us to do something reasonable for the web without messing with existing signage.
For our goal of visual compatibility with existing signage, one of the selection criteria is whether they preserve Helvetica’s distinctive “spur” on the capital G, something the words “Government of Canada” will make immediately noticeable. Overused Grotesk does this, and also stands out for having a web-friendly variable font version.

With font in hand, we can solve these accessibility and screen real-estate problems by using a proper font with Government branding.
To show how this can work, here is copy-paste friendly example of setting up Overused Grotesk in a new project so that it’s properly preloaded so that the page loads without the infamous Flash of Unstyled Text (FOUT).
Let’s use Rsbuild to scaffold a basic React application for us.
$ npm create rsbuild@latest
> npx
> create-rsbuild
◆ Create Rsbuild Project
│
◇ Project name or path
│ fontpreload
│
◇ Select framework
│ React 19
│
◇ Select language
│ TypeScript
│
◇ Select additional tools (Use <space> to select, <enter> to continue)
│ Add Biome for code linting and formatting
│
◇ Next steps ─────────────╮
│ │
│ 1. cd fontpreload │
│ 2. git init (optional) │
│ 3. npm install │
│ 4. npm run dev │
│ │
├──────────────────────────╯
│
└ All set, happy coding!
In this application we’ll need a copy of that Overused Grotesk font. We can use curl to both download the font put it in static/font which works nicely with Rsbuilds defaults.
curl 'https://raw.githubusercontent.com/RandomMaerks/Overused-Grotesk/refs/heads/main/fonts/variable/OverusedGrotesk-VF.woff2' --create-dirs --output-dir static/font --output OverusedGrotesk-VF.woff2
Rsbuild’s default template doesn’t include a lang attribute on the <html> element, or a <meta> description, so we’ll add a minimalist template in the static folder too.
cat << EOF > static/index.html
<!doctype html>
<html lang="en">
<head>
<meta name="description" content="Rsbuild application" />
</head>
<body>
<div id="<%= mountId %>"></div>
</body>
</html>
EOF
Now we’ll add some basic config for Rsbuild, telling it to use our template, skip bundling licence files, and most importantly to preload our font and other assets which is the key to avoid the Flash of Unstyled Text (FOUT).
patch rsbuild.config.ts <<'EOF'
diff --git a/rsbuild.config.ts b/rsbuild.config.ts
index c55b3e1..799d5ae 100644
--- a/rsbuild.config.ts
+++ b/rsbuild.config.ts
@@ -4,4 +4,29 @@ import { pluginReact } from '@rsbuild/plugin-react';
// Docs: https://rsbuild.rs/config/
export default defineConfig({
plugins: [pluginReact()],
+ html: {
+ // use a custom template to address A11y and SEO issues.
+ template: "./static/index.html",
+ tags: [
+ {
+ tag: 'link',
+ attrs: {
+ rel: 'preload',
+ type: 'font/woff2',
+ as: 'font',
+ href: '/static/font/OverusedGrotesk-VF.woff2',
+ crossorigin: 'anonymous',
+ },
+ },
+ ],
+ },
+ output: {
+ // This will prevent .LICENSE.txt files from being generated
+ legalComments: "none",
+ filename: {
+ // Don't use a hash in the font filename, so our tags above can
+ // reference the font files directly.
+ font: "[name][ext]",
+ },
+ },
});
EOF
Now we include an @font-face rule specifying where we want to load our font from. Rsbuild will run rspack on this file which will normally rewrite the src to point to the bundled file (something like src: url(/static/font/OverusedGrotesk-VF.1656e9bd.woff2)format("woff2");). Including filename.font: "[name][ext]", ensures that it doesn’t add that hash, so the name lines up with the name in our href in the tags section.
patch src/App.css << 'EOF'
diff --git a/src/App.css b/src/App.css
index 164c0a6..ae9754b 100644
--- a/src/App.css
+++ b/src/App.css
@@ -1,7 +1,15 @@
+@font-face {
+ font-family: "Overused Grotesk";
+ src: url("../static/font/OverusedGrotesk-VF.woff2") format("woff2");
+ font-weight: 300 900;
+ font-style: normal;
+ font-display: fallback;
+}
+
body {
margin: 0;
color: #fff;
- font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
+ font-family: "Overused Grotesk", Inter, Avenir, Helvetica, Arial, sans-serif;
background-image: linear-gradient(to bottom, #020917, #101725);
}
EOF
Now we can add a little text with a capital G, so that it’s easy to see that our font is loaded and used.
patch src/App.tsx << 'EOF'
diff --git a/src/App.tsx b/src/App.tsx
index dff1751..cebdc5b 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -3,7 +3,7 @@ import './App.css';
const App = () => {
return (
<div className="content">
- <h1>Rsbuild with React</h1>
+ <h1>Rsbuild with Overused Grotesk</h1>
<p>Start building amazing things with Rsbuild.</p>
</div>
);
EOF
And now it’s time to build our production bundle.
$ npm run build
> [email protected] build
> rsbuild build
Rsbuild v1.4.8
info build started...
ready built in 0.13 s
File (web) Size Gzip
dist/static/css/index.062da953.css 0.53 kB 0.34 kB
dist/index.html 0.63 kB 0.35 kB
dist/static/js/index.58333bd8.js 1.3 kB 0.78 kB
dist/static/font/OverusedGrotesk-VF.1656e9bd.woff2 85.1 kB
dist/static/js/lib-react.a4a8b05c.js 182.8 kB 57.9 kB
Total: 270.4 kB 144.4 kB
To get a sense of what this will look like in production, use npm run preview to get Rsbuild to serve us the production build files it just created in the dist folder. The Lighthouse scores are telling us we did this right.

This is pretty good so far. We have a font, and we’re loading it in a way that is good for web performance, but we haven’t really solved the larger problem with logos until we take one final step and make a signature block that uses it.
First, we’ll need to create a React component representing the Canadian flag. You might notice this component is created as a headless component, so that it’s easy to add ARIA attributes (important for accessibility) to and plays nicely with whatever approach you’re using for CSS (something like PandaCSS or Tailwind)
cat << EOF > src/Signature.tsx
import React from "react";
export function SVG({ children, ...props }: React.ComponentProps<"svg">) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
preserveAspectRatio="xMinYMin"
role="img"
width="65.669"
height="31.116"
{...props}
>
{children}
</svg>
);
}
export function Flag(props: React.ComponentProps<"path">) {
return (
<path
{...props}
d="m30.675 6.467 2.223-4.443 2.206 4.281c.275.452.499.415.938.2l1.898-.921-1.234 5.977c-.258 1.174.422 1.518 1.162.722l2.705-2.837.718 1.605c.241.485.605.415 1.086.328l2.794-.577-.938 3.464v.074c-.11.453-.33.83.186 1.05l.993.485-5.782 4.783c-.587.593-.384.776-.164 1.444l.532 1.605-5.372-.954c-.663-.162-1.124-.162-1.14.361l.219 6.048h-1.614l.22-6.031c0-.594-.461-.577-1.547-.357l-4.983.937.642-1.605c.22-.614.279-1.029-.22-1.444l-5.87-4.716 1.086-.651c.313-.237.33-.486.165-1.013l-1.104-3.505 2.831.593c.79.183 1.01 0 1.213-.414l.79-1.59 2.799 3.07c.494.577 1.196.2.976-.63l-1.344-6.48 2.08 1.174c.329.2.68.253.883-.124M50.099 0h15.57v31.116h-15.57ZM0 0h15.57v31.116H0Z"
/>
);
}
EOF
And finally we’ll import that into our App component to create a our new signature block. Notice how we can add styles and ARIA attributes as needed, without worrying about a customizability wall.
patch src/App.tsx << 'EOF'
diff --git a/src/App.tsx b/src/App.tsx
index cebdc5b..f9f58f9 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,9 +1,26 @@
import './App.css';
+import { Flag, SVG } from "./Signature.tsx";
const App = () => {
return (
- <div className="content">
- <h1>Rsbuild with Overused Grotesk</h1>
+ <div className="content" style={{ justifySelf: "center" }}>
+ <section
+ style={{ display: "flex" }}
+ >
+ <SVG>
+ <title>Canadian Flag</title>
+ <Flag style={{ fill: "#ea2d37" }} />
+ </SVG>
+ <span
+ style={{
+ paddingLeft: "0.8em",
+ lineHeight: "1em",
+ textAlignLast: "left",
+ }}
+ >
+ Government of<br /> Canada
+ </span>
+ </section>
<p>Start building amazing things with Rsbuild.</p>
</div>
);
EOF
The result is super satisfying, a razor-sharp and accessible signature block looks great at any zoom level and on any screen size. It’s easily styled, and works really well with internationalization libraries like the one I covered in a previous post.

Using an Open Source font to maintain visual compatibility with FIP feels like win-win: Nobody needs to change physical signage/letterhead, lingering accessibility problems can be solved and the user experience for every government web site improves a little… all for a cost of $0.






