How to Use Custom Fonts in VOLT Themes and Element Blocks

Custom font faces are easy to incorporate into your VOLT Store using a wide variety of built-in fonts in VOLT’s Site Designer. To use other fonts, it is easy to build a custom Block using Element.

Introduction

Choosing a font is a fundamental aspect of web design, and VOLT offers numerous ways to select the perfect font for your ecommerce store.

VOLT’s Site Designer offers a generous list of available fonts already built-in to every theme. No prior knowledge is required to use the built-in fonts discussed in the first section of this article.

The remainder of this article is for developers of custom Blocks using Element to learn how to add new fonts to custom Blocks built for the VOLT Store. Building custom Blocks with Element allows you total customization of the fonts used in your VOLT Store. Whether you choose to use built-in fonts or custom Blocks, you will also learn how to select fonts that are compatible with Google AMP (Accelerated Mobile Pages).

The Easy Way: Built-in Fonts Available in All Themes

All VOLT Store themes come with access to a variety of built-in fonts inside VOLT’s Site Designer.

To access the font face selector, first open up a theme, then open up Design Settings by clicking the Design Settings button in the top-middle of your screen.

Scroll down in the sidebar that appears at left, and you will find a section labeled Typography. Here, you can choose font faces (called font families) for headings and basic text in this section.

Here’s the list of built-in fonts: DM Sans, Exo 2, Heebo, Karla, Lato, Lora, Merriweather, Montserrat, Muli, Nunito, Nunito Sans, Old Standard TT, Open Sans, Oswald, Oxygen, Poppins, Playfair Display, PT Serif, Ramaraja, Red Hat Display, Roboto, and Work Sans.

Any of these fonts will be immediately applied to the preview of your VOLT Store as soon as you click on them. Feel free to try many different combinations!

To save your changes, scroll to the bottom of the sidebar where you selected the font and click the Done button.

Your changes will not go live on your VOLT Store until you click the Publish button at the top-left to publish the current version of your theme.

For more information, please see the section on typography in the tutorial Design A New Theme With Site Designer from the Element Platform Documentation. 

Google AMP and Font Faces

Google AMP (Accelerated Mobile Pages) is a style of building websites optimized for blazing-fast speed. One amazing feature of VOLT is that it creates AMP pages automatically. The built-in fonts already work with Google AMP in VOLT. No further setup is needed.

What’s the Benefit of AMP?

According to Google, AMP pages automatically appear in Google search results on mobile devices. AMP pages can potentially rank higher in mobile search results than non-AMP pages because speed is a ranking factor for Google search.

To view the AMP version of your store, add /googleamp/ following your VOLT Store URL, such as:

https://my-volusion-store.myvolusion.com/googleamp/ 

You can double-check that your VOLT Store’s AMP version is working correctly using Google's AMP testing tool or the AMP validator extension for Google Chrome. 

Are Custom Fonts Compatible with AMP?

For custom Blocks, fonts have to follow certain guidelines provided in the AMP documentation:

“AMP pages can’t include external stylesheets, with the exception of custom fonts. You can embed custom fonts into your page in two ways:

Through a <link> tag (white-listed font providers only)

Via @font-face (no restrictions, all fonts allowed)” —AMP Docs 

Next, you will learn how to make a custom Block that loads a Google Font via the @font-face CSS property.

Create a Custom Block to Add Additional Font Faces

For fonts that are not already built-in to the VOLT Store, you will need to make a custom Block to add additional font faces.

The rest of this tutorial assumes that you know how to create and publish a custom Block for your VOLT Store using Element.

To learn how to make a custom Block, please read the 15-minute article “Building An Element Page Tutorial” from the Element Platform Documentation. You may also want to watch the YouTube playlist “Element Tutorial | VOLT Learning Center” (27 minutes total).

You will need authorization from Volusion to develop Blocks before beginning this tutorial. Please refer to the page “How To Get Approved To Develop Blocks” from the Element Platform Documentation.

This tutorial will show you how to build a custom Block using a Google Font, which is one of the AMP-approved font providers.

Picking a font face

Only certain font providers can be used in AMP pages, at least using a <link> tag, according to the AMP documentation. These are the approved providers:

  • Typography.com: https://cloud.typography.com
  • Fonts.com: https://fast.fonts.net
  • Google Fonts: https://fonts.googleapis.com
  • Typekit: https://use.typekit.net
  • Font Awesome: https://maxcdn.bootstrapcdn.com, https://use.fontawesome.com” —AMP Docs 

Those resources are also useful for finding fonts for your custom Block.

The method used in this tutorial demonstrates the concept of using a custom font in a custom Block first using the <link> method.

This tutorial continues on to demonstrate the more-flexible @font-face CSS property.

The <link> method will not work on Google AMP versions of custom Blocks, because the stylesheets are being loaded from inside the Block.

For Google AMP compatibility, no external stylesheets are allowed, except for custom fonts in the <head> tag.

This is how VOLT’s Site Designer loads the selected heading and base fonts in the <head> tag using an external <link> to the appropriate Google Font, which is why all built-in fonts are compatible with Google AMP by default.

When working inside a custom Block, you cannot modify the <head> tag in the Google AMP version of the page, so the <link> method will not work.

The @font-face method will work on Google AMP pages of custom blocks, because no modification to the <head> tag needs to happen from inside custom Blocks.

You will be learning how to build an AMP-compatible custom Block using @font-face.

To start building the custom Block, first pick which font face you would like to use in your custom Block.

How to pick fonts using Google Fonts

Open a web browser and navigate to https://fonts.google.com/ (Google Fonts).

To pick a font in Google Fonts, click on it in the list of fonts, then choose your desired font weights (such as Regular 400 and Bold 700) by clicking the + Select this style button.

Once satisfied with your selections, click the Embed tab in the right-hand sidebar.

You will need the <link> and the CSS rules later in this tutorial.

This tutorial will use the font faces “Dancing Script” (a cursive script) and "Fira Code" (a monospaced font), which are both variable fonts.

What are variable fonts?

Variable fonts allow the use of bold and italic font styles with a reduced file size.

However, variable fonts are not supported in older browsers including Internet Explorer.

For details, please refer to the browser compatibility chart for variable fonts at CanIUse.com.

Using variable fonts is in no way a requirement of using a custom font inside VOLT.

How Element handles custom CSS

The Element platform uses Aphrodite, a “CSS-in-JS” (also called “JSS”) package to provide CSS styling of custom Blocks. 

For more information on using CSS in Element, please read the article Styling Your Block With CSS from the Element Platform Documentation.

For specific information on using Aphrodite to write custom CSS classes, please refer to the article How To Style a Block With Aphrodite from the Element Platform Documentation.

This tutorial uses the principles explained in that article to build a new custom Block with custom font faces.

This article will first demonstrate simply adding a custom font face to the Element Starter Block (i.e. the default custom Block created with the Element CLI using the element new command).

The tutorial will then conclude by creating a dynamic implementation of the “font-family” CSS property using the “one-of” Element Proptype to create a dropdown menu.

Create a new custom Block to add the font to

You may already be logged in to the Element Command Line Interface (CLI). If not, then enter the element login command into your terminal:

element login

This login command will prompt you for the username and password that you use with VOLT’s Site Designer.

Once logged in, begin by making a new custom Block using the Element CLI in your terminal:

element new CustomFontFaceBlock
cd CustomFontFaceBlock
npm install

Next, initialize a git repository in the directory to track changes with the commands:

git init
git add -A
git commit -am "Initial Commit"

Now would be a good time to publish the repository online, such as to GitHub, for backup and collaboration. (Please refer to Adding a repository from your local computer to GitHub if you are using GitHub Desktop.)

Edit your /src/getStyles.js file

Open up the /src/getStyles.js file from your custom Block in a text editor or IDE (such as VS Code). You will need the CSS rules from the Google Font.

Replace the contents of the file with the following code:

export const getStyles = (blockConfig) => ({
example: {
fontSize: "2rem",
fontFamily: "'Dancing Script', cursive",
fontWeight: "bold", // or "normal"
},
})

You are just adding the new CSS rules to Element’s default starter Block, which uses a CSS class called “example” to style text.

Note that you are writing Javascript-based CSS, so the CSS rule names are in camelCase and not hyphenated. That means you reference fontFamily and fontWeight instead of the CSS rules font-family and font-weight. 

Edit your /src/Block.js file

Open up the /src/Block.js file of your custom Block in your text editor or IDE. You will need the <link> information from the Google Font.

Replace the entire contents of the file with the following:

import React, { useEffect } from "react
import { css, StyleSheet } from "aphrodite/no-important"
import { getStyles } from "./getStyles"
import { defaultConfig } from "./configs"

const Block = (props) => {
// React's Effect Hook (useEffect) runs a function when the Block is rendered
useEffect(
() =>
// Add a link to the font stylesheet
props.utils.addLink(
"https://fonts.googleapis.com/css2?family=Dancing+Script:wght@400;700&display=swap"
),
[]
)

// The second parameter is an empty array, [], to make useEffect run just once
const classes = StyleSheet.create(getStyles(props))
return <h1 className={css(classes.example)}>{props.text}</h1>
}

Block.defaultProps = defaultConfig
export default Block

This code uses the addLink function (props.utils.addLink), which is defined in the /src/index.js file. This function simply adds a stylesheet to the <head>.

In this case, addLink adds the stylesheet loading the “Dancing Script” font from Google Fonts.

Note that only the “href” portion of the <link> tag from Google Fonts is actually passed as the argument to the addLink function.

The addLink function is called just once, when the custom Block first loads, which will be explained in the next section.

Examining React’s Effect Hook

The custom Block code above calls the addLink function inside a function useEffect, which is a React Hook.

For those familiar with React’s class-based lifestyle methods the Effect Hook (useEffect) is similar to componentDidMount and componentDidUpdate by default.

In plain English, that means the code in the useEffect block is run once the Block mounts (loads) and again every time the Block updates for any reason.

However, passing an empty array to useEffect as its second parameter causes the code in the Effect Hook to only run once, when the Block first loads. Without the Effect Hook, the stylesheet would get added to the <head> tag repeatedly, on every render (everytime the Block refreshes its display).

If you had multiple custom Blocks all referencing a single custom font, only one Block would actually need to load the stylesheet for that font. Again, because of the modification to the <head> tag necessary, this method of loading custom fonts using <link> is not compatible with Google AMP.

Start the local server to view the results

Launch your local development environment by entering the npm run start command in your terminal:

npm run start

This will open a new window in your browser pointing to http://localhost:4000/ so you can examine the new custom Block.

Note that the local Google AMP version of the page will work, but your custom font will not work in the Google AMP version of a live VOLT Store, because of the <link> method. The next section will cover the more powerful @font-face method.

If you would like to publish the Block to try it out in VOLT’s Site Designer, then you will need to build and publish the block. In your terminal window, 

npm run build

The default tests will be passing, so they do not need to be updated.

Next, publish the Block using the Element CLI with the element publish command with the required -n (“name”) flag:

element publish -n "Custom Font Face Block"

Please note that the name of the custom Block needs to be in quotes. The Element CLI will prompt you to select the category for this Block using your arrow keys. Choose Titles by scrolling down using the down arrow; then hit the Enter key.

You will see a warning that no image exists for your “thumbnail.png” file. This means that there is no thumbnail image for your custom Block to display in VOLT’s Site Designer.

For help adding a thumbnail, please watch the YouTube video How to Create a Thumbnail for Your Block | Element Tutorial | VOLT Resource Center (4 minutes) or read the Element CLI’s publish command documentation.

For information on publishing Blocks, please refer to the Element CLI’s publish command in the Element Platform Documentation.

Continue reading to learn how to improve the custom Block to use a drop-down menu to select the font face and the weight of the font (regular or bold).

Build a dynamic custom Block with drop-down font selection

Element is a powerful framework for customizing your VOLT Store, and it is easy to make a custom Block with a dynamic CSS selector. The rest of the article will show you how to make a custom Block that allows the user to select the custom font.

You will be using the one-of Element Proptype to create a drop-down menu. The user will be able to select the font-family and font-weight CSS properties based on the inputs that you will specify. While only two fonts in two weights will be demonstrated in this tutorial, you are free to use as many combinations as you would like in your own custom Block.

Next, you will start building the improved custom Block. If you already were following along in a new custom Block, you can continue editing the same files to upgrade it.

Edit your /src/configs.js file

In your text editor or IDE, open up your /src/configs.js file. You will need the CSS rules for the Google Font you plan to use. These were found on the Google Fonts page previously discussed, in the sidebar labeled Embed.

Replace the text of the entire /src/configs.js file with the following code:

import { ElementPropTypes } from "@volusion/element-proptypes"

export const configSchema = {
text: {
label: "Text content",
type: ElementPropTypes.string,
},
fontFamily: {
label: "Font family",
type: ElementPropTypes.oneOf([
`"Dancing Script",cursive`,
`"Fira Code",monospace`,
]),
},
fontWeight: {
label: "Font weight",
type: ElementPropTypes.oneOf(["normal", "bold"]),
},
}

export const defaultConfig = {
text: "Element Starter Block",
fontFamily: `"Fira Code",monospace`,
fontWeight: "bold",
}

This code establishes three configurable props for use in your Custom Font Face Block. These props will be editable by the user of the custom Block in VOLT’s Site Designer.

To customize your font, you would replace the text inside the fontFamily (i.e. `"Dancing Script",cursive`) with your CSS rules from Google Fonts. This text specifies your desired font family as well as a fallback font. 

For ease of testing the custom Block later, single-quotes were changed to double-quotes and the extra spaces were removed in the CSS rule:

`"Dancing Script",cursive` // instead of "'Dancing Script', cursive"

As previously mentioned, this tutorial uses the “one-of” Element Proptype, which creates a drop-down menu of the listed options in the array.

Each CSS rule from the Google Font should be listed as an option in the fontFamily prop’s configuration. The same exact text needs to appear in whatever is used for the defaultConfig setting provided in this file.

Font weights can be listed as words (“normal” and “bold”) or numeric values (“400” and “700”) depending on your preference.

Getting your Google Font’s @font-face

You will need the <link> information for the Google Font that you plan to use. Again, this information is found on the aforementioned Google Fonts page.

To retrieve the exact URL that you need, you need to browse to the provided URL from the href section of the <link>. For example, this is the URL for “Dancing Script”:

https://fonts.googleapis.com/css2?family=Dancing+Script:wght@400;700&display=swap 

Navigate to this URL in a web browser, and scroll to the bottom. In the section labeled /* latin */ you will need to copy the font-family and src properties from this CSS file:

/* latin */
@font-face {
font-family: 'Dancing Script';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(https://fonts.gstatic.com/s/dancingscript/v14/If2cXTr6YS-zF4S-kcSWSVi_sxjsohD9F50Ruu7B1i03Sup8.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

Note that you need the entire property labeled src, including the section that says format.

Next, you will be linking to this URL by making a @font-face inside your custom Block.

Edit your /src/getStyles.js file

Open up the /src/getStyles.js file of the custom Block in your text editor or IDE.

Replace the contents of the file with the following:

export const getStyles = (blockConfig) => {
const { fontFamily, fontWeight } = blockConfig
const fontDancingScript = {
fontFamily: "Dancing Script",
src: `url(https://fonts.gstatic.com/s/dancingscript/v14/If2cXTr6YS-zF4S-kcSWSVi_sxjsohD9F50Ruu7B1i03Sup8.woff2) format('woff2')`,
}
const fontFiraCode = {
fontFamily: "Fira Code",
src: `url(https://fonts.gstatic.com/s/firacode/v8/uU9eCBsR6Z2vfE9aq3bL0fxyUs4tcw4W_NprJVD7Ng.woff2) format('woff2')`,
}

// Add backup fonts to prevent invisible text on network errors
let fontFaceCSS
if (fontFamily.match("Dancing Script")) {
fontFaceCSS = [fontDancingScript, "cursive"]
}
if (fontFamily.match("Fira Code")) {
fontFaceCSS = [fontFiraCode, "monospace"]
}

return {
example: {
fontFamily: fontFaceCSS,
fontWeight: fontWeight,
// The following are other defaults from Google Fonts:
fontStyle: "normal",
fontDisplay: "swap",
},
}
}

In this code, the CSS rules applied to the class, font-family (fontFamily) and font-weight (fontWeight), are set dynamically from the props provided to the Block.

In order to do this, you make JavaScript objects that represent a @font-face when interpreted by Aphrodite, the CSS-in-JS package used by Element.

The fontFamily property needs to be passed to Aphrodite as an array, which should contain fonts (built as @font-face objects) and strings (for the fallback fonts).

In the /src/getStyles.js file, the JavaScript String.prototype.match() method is used to check which font should be used in order to add the fallback fonts. The fallback fonts need to be entered manually, in a slightly different format from the CSS rules seen previously:

fontFaceCSS = [fontDancingScript, "cursive"] // `"Dancing Script",cursive`

You may have noticed that the CSS class is still called “example” in this tutorial. This may not be the clearest class name to be using in your custom Block. Feel free to change the class name to fit your needs in this file and all following files.

Edit your /src/Block.js file

Open the /src/Block.js file again in your text editor or IDE.

In this case, all the styles are handled by Aphrodite, so the Block has nothing to do.

Revert the /src/Block.js file back to its initial state, from the starter Block (created using element new) by replacing the contents of the file with the following code:

import React, { useEffect } from "react"
import { css, StyleSheet } from "aphrodite/no-important"
import { getStyles } from "./getStyles"
import { defaultConfig } from "./configs"

const Block = (props) => {
const classes = StyleSheet.create(getStyles(props))
return <h1 className={css(classes.example)}>{props.text}</h1>
}

Block.defaultProps = defaultConfig
export default Block

All the magic happens in the getStyles function call, which is discussed in the next section.

Understanding the getStyles function

The getStyles function (/src/getStyles.js) is provided the props as an argument and then returns a JavaScript object where each specified class name is a property.

The value of each class name is another JavaScript object, one that links CSS rule names (also called CSS properties) to the desired values.

The getStyles function tells Aphrodite (the CSS-in-JS package) how to convert your props into CSS styles.

In this case, you are creating an example class with fontFamily specified by the prop fontFamily and fontWeight by the prop fontWeight.

Aphrodite combines these elements into what we want, creating a custom class for the heading text in our custom Block (/src/Block.js file):

const classes = StyleSheet.create(getStyles(props))
return <h1 className={css(classes.example)}>{props.text}</h1>

The result is that you provide the user of your custom Block with dynamic control over the font face and weight of the text.

For additional information on using custom CSS in Element, please read the article Styling Your Block With CSS in the Element Platform Documentation. 

Try out the Block

To test the capabilities of the custom Block, you can use the npm start command in a terminal window to start the local development server:

npm run start

This should open a browser window. If it does not, then browse to http://localhost:4000/  

You might want to edit the /local/index.js to simulate a user changing the props passed to your custom Block. Replace the variable localEnvPropOverrides with the following:

const localEnvPropOverrides = {
text: "Custom prop value for local testing",
fontFamily: `"Dancing Script",cursive`,
fontWeight: "normal",
}

Now you should see the font face change in your browser preview of your custom Block.

Moving on, you will test and then publish the custom Block using Element.

Unit testing the custom Block

You need all tests passing to publish a custom Block with Element and make it available to use in a theme in your VOLT Store.

Open the file /__tests__/Block.spec.js and replace the code with the following:

import React from "react"
import { mount } from "enzyme"
import {
mockUtils as utils,
joinClasses,
} from "@volusion/element-block-utils/test-utils"
import { block as Block, defaultConfig } from "../src"
import { flushToStyleTag } from "aphrodite"

let props
describe("The Block", () => {
beforeEach(() => {
props = {
data: {},
utils,
joinClasses,
queryParams: {},
}
})
it("renders without errors", () => {
mount(<Block {...props} />)
})

On the next line, add tests for when the Block loads using the default data:

 describe("when there is no custom data", () => {
it("should render the block with the default content", () => {
const wrapper = mount(<Block {...props} />)
expect(wrapper.text()).toBe(defaultConfig.text)
})
it("should render the block with the default font faces", () => {
const wrapper = mount(<Block {...props} />)
// Force Aphrodite to output the CSS-in-JS styles in time to test them:
flushToStyleTag()
const h1Element = wrapper.find("h1").at(0)
// Make sure our CSS-in-JS decorator successfully injected the CSS class
expect(h1Element.hasClass(/example_(\w+)/)).toBe(true)
// Expect the computed CSS style to match the default heading font sizes
const h1Styles = getComputedStyle(h1Element.getDOMNode())
expect(h1Styles.getPropertyValue("font-family")).toBe(
defaultConfig.fontFamily
)
expect(h1Styles.getPropertyValue("font-weight")).toBe(
defaultConfig.fontWeight
)
})
})

On the following line, add tests for when the Block loads using custom data:

  describe("when given custom data", () => {
it("should render the block using the custom data", () => {
const customText = "Custom Block Text"
const wrapper = mount(<Block {...props} text={customText} />)
expect(wrapper.text()).toBe(customText)
})
it("should render the block with the custom font faces", () => {
const customFontFamily = `"Dancing Script",cursive`
const customFontWeight = "normal"

const wrapper = mount(
<Block
{...props}
fontFamily={customFontFamily}
fontWeight={customFontWeight}
/>
)
// Force Aphrodite to output the CSS-in-JS styles in time to test them:
flushToStyleTag()
const h1Element = wrapper.find("h1").at(0)
// Make sure our CSS-in-JS decorator successfully injected the CSS class
expect(h1Element.hasClass(/example_(\w+)/)).toBe(true)
// Expect the computed CSS style to match the default heading font sizes
const h1Styles = getComputedStyle(h1Element.getDOMNode())
expect(h1Styles.getPropertyValue("font-family")).toBe(customFontFamily)
expect(h1Styles.getPropertyValue("font-weight")).toBe(customFontWeight)
})
})
})

Next, open the file /__tests__/AMP.spec.js, and replace the code with the same code as /__tests__/Block.spec.js. You only need to change one line, line 16, to read:

utils: { ...utils, isAmpRequest: true },

You can run the tests using the command npm run test in a new console terminal:

npm run test

That command will open a watch window where the tests will automatically be run every time any file changes in your custom Block. To close it, press Ctrl+C.

For more information on how these tests work, please refer to the previous article on testing the CSS of custom Blocks.

Build, Publish, and Release the Custom Block

If you are satisfied with the results in the local environment (npm start), then it is time to check the functionality of your custom Block in VOLT’s Site Designer.

First, build the custom Block by running the npm run build command in a terminal window:

npm run build

If you did not publish it before, publish the custom Block using the Element CLI in a terminal window, using the -n flag to specify a name

element publish -n "Custom Font Face Block"

As noted previously, when publishing a Block, you will need to select a category using the arrow keys and Enter, and you will see a warning about no thumbnail image.

If you published the Block already, then run the command element update in your terminal window to release a new minor version of your custom Block:

element update

Your custom Block is now available in VOLT’s Site Designer for you to experiment with.

The minor version change will immediately take effect on any themes using that Block in the VOLT Store, but your most recent changes are “staged” — only available using the Preview button in VOLT’s Site Designer.

Staged Blocks do not appear when clicking the Publish button in VOLT’s Site Designer until they are “released” to production.

When you are ready for the Block to be available on live VOLT Stores, then release it from staging to production with the command:

element release

This will make your custom Block public, meaning it will appear in public VOLT Stores that have published a theme containing your Block in VOLT’s Site Designer.

Conclusion

VOLT has excellent customization features allowing you to use any font that you wish in your VOLT Store. There are tons of built-in custom fonts available for use in VOLT’s Site Designer, and they are all compatible with Google AMP.

If you need more control over the fonts used in the design of your VOLT Store, you can build a custom Block using Element. Custom Blocks can be set up to give the user direct configuration over font face and font weight, as shown in this tutorial. When building a custom Block using Element, you should be sure to keep the use of fonts compatible with the Google AMP guidelines. 

The custom Blocks discussed in this article follow these guidelines and are compatible with Google AMP. Testing custom Blocks is important for reliability and prevention of future maintenance issues. This article demonstrated writing unit tests for a custom font in your Element Block.

To provide a user further customization of font styles in your VOLT Store, you could combine this tutorial with the previous article on controlling font size in a custom Block. The previous article shows how font size can be a dynamic, user-configurable property of a custom Block, which dovetails perfectly with the custom font face and font weight described in this article.

VOLT gives you the power to use exactly the right font for your ecommerce store.