Putting a (link/meta) bow on it

Beyond rendering directly in browsers themselves, web pages also exist in the context of search engines, social media, messaging, and other sharing. We’ve gathered a handful of practices here which adjust and optimize how your site appears through these lenses—via special <link> and <meta> elements that live in your page’s <head>. No site is truly complete without considering these.

Favicons and sharing images

iOS/Mobile Safari.

The first of these is the favicon (for favorite icon)—which appears in the browser’s tabs/address bar, bookmarks, history, and also on search engine entries. This is often a logo—though they don’t always translate down well in size. Sometimes it is its own thing. But it is always an important part of the initial impression of your site, and should be carefully considered and constructed.

You’ll find a lot of scammy, ad-ridden favicon generators out there. We’re going to do it manually, with a minimal, best-practice (for 2023) approach.

The humble favicon.ico (Safari)

The favicon format is .ICO—from ancient, original Windows icons. It is a package/directory format, meaning it can contain several, discrete, raster icon sizes: 16×16px, 32×32px, 64×64px. (We’ll use different elements for our other/larger needs.)

These are (unfortunately) still needed today because of several, long-standing browser quirks:

You should draw each size individually, if necessary—pixel-tuning each version to be legible and crisp at its dimension. Use Figma’s pixel preview (set at 1x), toggled with   P (command-shift-P).

Draw an artboard/frame for each size.

Note that these can have transparent backgrounds, and that HiDPI (2x/retina) displays will render their device-native size—so most folks are seeing your 32px version, these days. Export a PNG for each dimension, from Figma, into your project folder.

These can be combined together in an ICO with ImageMagick—the appropriately named Dark Arts tool at the bottom of every imaging pipeline. (If you’re on a Mac, some version of this is likely already installed; PCs might need to download it). You’ll run this terminal command, in your project folder:

convert 16.png 32.png 64.png -compress zip favicon.ico

You can open a terminal in VS Code with  ` (control-backtick/tilde).

You should still specify/include the resulting favicon.ico in your <head>, allowing you to organize/move it out of the root:

	<title>Typography and Interaction</title>
	<link href="/assets/favicon.ico" rel="icon" sizes="any">
	<!-- The rest of your head… -->

Note we’re omitting the responsive viewport element here, for simplicity. But your <head> should have this along with all your stylesheets and JS. Just the metadata, here.

A few other (Safari) concerns:

Safari added the white, here.

Oh, Safari. I wish I knew how to quit you.

As of writing, we still couldn’t find a decent online converter that packaged multiple ICO dimensions. So this is somewhat… noodly, but we think it is the best, cleanest way.

Modern SVGs (Chrome)

Chrome is decidedly better, here. It supports SVGs for favicons, which gives us the benefit of the vector format—resolution independence. One file, no intermediate/terminal steps, for different display sizes and densities. It is still a good practice to draw these at 16×16px—so you can pixel-tune—then export from Figma, now as an SVG.

You should add them to your <head> as a progressive enhancement for Chrome, after the previous <link>; Safari will just ignore them:

	<title>Typography and Interaction</title>
	<link href="/assets/favicon.ico" rel="icon" sizes="any">
	<link href="/assets/favicon.svg" rel="icon" type="image/svg+xml">
	<!-- The rest of your head… -->

SVGs have another benefit: since they can include self-contained, internal <style> elements—we can alter/adjust our favicon with prefers-color-scheme (light/dark mode) media queries!

<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
		#ampersand { fill: #000000; }

		@media (prefers-color-scheme: dark) {
			#ampersand { fill: #ffffff; }
	<path id="ampersand" d="M10.388 6.015h3.199v.282c-.442.035-.77.134-.983.297-.208.157-.535.64-.982 1.447-.447.807-.95 1.561-1.508 2.262.452.528.855.899 1.21 1.112.356.208.714.312 1.075.312.35 0 .647-.094.89-.282.244-.193.417-.474.519-.845l.281.206c-.187.716-.49 1.244-.906 1.584a2.23 2.23 0 0 1-1.455.51c-.416 0-.84-.112-1.272-.335-.426-.229-.893-.612-1.401-1.15-.63.558-1.198.947-1.706 1.165a4.09 4.09 0 0 1-1.615.32c-.838 0-1.503-.223-1.995-.67-.493-.447-.739-.98-.739-1.6 0-.614.22-1.226.663-1.835.441-.615 1.272-1.25 2.49-1.904-.238-.528-.4-.96-.487-1.295a3.964 3.964 0 0 1-.13-.975c0-.868.32-1.53.96-1.988A2.85 2.85 0 0 1 8.194 2.1c.605 0 1.097.18 1.478.54.38.356.571.796.571 1.318 0 .539-.185 1.01-.556 1.417-.365.406-1.015.85-1.95 1.333a30.935 30.935 0 0 0 2.019 3.153c.893-1.066 1.34-1.965 1.34-2.696a.949.949 0 0 0-.228-.625.699.699 0 0 0-.48-.243v-.282Zm-2.91.198c.63-.3 1.1-.64 1.41-1.02.314-.381.472-.805.472-1.273 0-.365-.115-.667-.343-.906a1.1 1.1 0 0 0-.838-.358c-.442 0-.777.155-1.005.465-.224.304-.335.604-.335.898 0 .25.043.528.13.838.085.305.256.757.51 1.356Zm1.181 4.76c-.67-.914-1.135-1.582-1.394-2.003a20.15 20.15 0 0 1-.853-1.569c-.61.35-1.069.736-1.378 1.158a2.293 2.293 0 0 0-.457 1.37c0 .544.175 1.021.525 1.433.35.41.823.617 1.417.617.32 0 .627-.064.921-.19.3-.128.706-.4 1.219-.816Z" />

You would export your SVG from Figma, then manually add the <style> (and id), as here.

Light mode.
Dark mode.

You may or many not want to do this—it entirely depends on how you are using your favicon. We thought the blue background was our real brand—not the ampersand form itself—and so didn’t use this method.

And apple-touch-icon

When the iPhone (with Mobile Safari) came on the scene in 2007, it added its own tag for webpage icons—now commonly known as touch icons—visible when adding pages to your home screen and in bookmarks, frequently-visited lists, and messages.

In Messages.

As everyone rushed to… respond to the iPhone, this syntax stuck and became the de facto standard—Android and Chrome use the same rel="apple-touch-icon" syntax, and for similar uses. In lieu of larger/specific images (more on that below), you should think of this as your default share image.

This should be an opaque (no transparency) PNG, at around 256×256px. Again, add it in your <head>, below the others:

	<title>Typography and Interaction</title>
	<link href="/assets/favicon.ico" rel="icon" sizes="any">
	<link href="/assets/favicon.svg" rel="icon" type="image/svg+xml">
	<link href="/assets/touch.png"  rel="apple-touch-icon">
	<!-- The rest of your head… -->

Note that we used the same image content as our favicon, here—but with the larger sizes, you might want to use this type distinctly. Think of how these are used/shown differently, and interpret this for your work!

Open Graph, structured data / metadata

As sharing contexts became more and more prevalent, other approaches were developed to add additional information around pages in these scenarios—using special <meta> tags in the <head>.

Here, Facebook led the charge—what the iPhone was for the mobile web, Facebook was for sharing. They developed the Open Graph protocol, which became the standard and is used now in many (usually, non-Facebook) contexts. (Graph here is used with the maths meaning.)

This type of added info, broadly, can be referred to as structured data or metadata—hence Facebook’s name change.


So beyond your favicon and touch image, you can also specify an og:image (OG for… Open Graph) in your <head>. This is often used for more page-specific images: the main photo for a news article, the product shot in e-commerce, and so on. These are generally made visible when sharing a link on Facebook, LinkedIn, Slack, Messages, etc.—where these sites/apps generate a share card or preview for the URL.

Slack shows the whole image.
LinkedIn crops in to 16:9.

These can now be JPGs (for more photographic content), or PNGs (again, opaque). Tradition (inertia) suggests Facebook’s original 1200x630px dimension—but every context/app handles these differently. A better, modern rule-of-thumb is an image around 1200px on the long edge, at its original/best aspect-ratio.

These are again specified in your <head>, now with <meta> elements:

	<title>Week 24</title>
	<link href="/assets/favicon.ico" rel="icon" sizes="any">
	<link href="/assets/favicon.svg" rel="icon" type="image/svg+xml">
	<link href="/assets/touch.png"  rel="apple-touch-icon">
	<meta content="cookie-cutter.jpg" property="og:image">
	<meta content="A six-sided, cubed, metal cookie cutter." property="og:image:alt">
	<!-- The rest of your head… -->

Note these allow an alt text for accessibility, in a separate tag.

Title and description

Open Graph also specifies og:title and og:description properties. However, we already have a <title> element—and there was an existing convention around descriptions—which browsers, apps, and search engines continue to use.

So we think including redundant og: versions for title/description is often unnecessary. (SEO/snake-oil folks might disagree.) If you are worried—or your boss tells you to—you could duplicate the tags. One reason might be to tailor different content (like your description length), for different platforms. But we don’t think it is worth it, most of the time.

Again, different apps are going to display/use this information in their own way—so there are no hard rules on length, and you’ll want to check the contexts you care about. Generally, tweet length (err, toot length?) works well—so somewhere around 140 characters. And titles and descriptions should always be plain text—no HTML. You can usually use entities or encoded non-breaking spaces, though!

We’ll add in a description, to our <head> stack:

	<title>Typography and Interaction</title>
	<meta property="description" content="Typography and Interaction is a year-long, two-semester course in the MPS Communication Design program at Parsons / The New School. The class will provide a rigorous foundation of typographic and interaction principles in the context of digital design. (We hope.)">
	<link href="/assets/favicon.ico" rel="icon" sizes="any">
	<link href="/assets/favicon.svg" rel="icon" type="image/svg+xml">
	<link href="/assets/touch.png"  rel="apple-touch-icon">
	<!-- The rest of your head… -->
Google makes its snippet from your description—but it will also show other text there, based on your search. It also might decide to show your images, or not! Ultimately, you can only suggest these things.

Audio and video

Messages allows inline media.

Some sharing contexts even let you play audio or video directly, in situ, from a share card. This might be useful for sites oriented around media, like Spotify or YouTube—but keep in mind the user is then not visiting the pages themselves, which you might prefer.

These are specified much like images, with the og:audio and og:video properties. There are extra metadata properties associated with the different types.

Conceptually, do you want your shared URL to function only as a link? Or somewhat as the thing itself?

Schema and web app manifests

Beyond this, there is a (very, very) long tail of metadata/structured-data uses. Much of it will depend on the nature of your project/work, and there will be sub-conventions within conventions.

After Open Graph, the most common structures you might encounter next are probably Schema.org, oriented around search engine (Google) snippets—and Web app manifests (manifest.json), used by progressive web apps.

Not to dig too hard into SEO true-believers—but you will find a lot of junk out there, suggesting the right combination of <meta> elements will yield riches. Take it all with a big grain of salt (and a patent medicine chaser). You can read up on what Google actually suggests, but otherwise focus on your content and semantics—your time (and someone’s money) is better spent there.

Other things for your <head>


This usually isn’t explicitly needed these days—because browsers assume/default to it—but you might have seen it in our examples and on other sites:

<meta charset="utf-8">

This specifies your document’s character encoding as UTF-8, a superset of basic ASCII. Long story (very) short—this allows you to use encoded non-latin characters (👋 and emoji) directly in your HTML. To be thorough/explicit, you can include this tag.


Finally, another recent <head> quirk: you can specify a theme-color, which is used by (some) browsers to tint/color their own UI around/outside of the page:

<meta content="blue" name="theme-color">

This changes with pretty much every OS release—but as of writing, usually only shows up on Mobile Safari and Mobile Chrome. (Desktop Safari default settings have it off; Desktop Chrome has never shown it.)

Safari tries to infer this color from your <body> background (and choses a contrasting UI text color)—but with complicated pages it might guess these wrong. You might also just want to adjust it, based on your design.

Safari correctly guessed our blue.
But maybe we’d rather hide that dynamic island.