Best practices for @remotion/layout-utils
Take note of the following points to ensure correct measurements when using the @remotion/layout-utils package.
These tips apply to all of measureText(), fitText(), and fillTextBox().
Wait until the font is loaded
Only call measureText() after the font is loaded. This applies to Google Fonts (example below) or any other font loading mechanism.
MyComp.tsxtsximport {useState ,useEffect } from "react";import {Dimensions ,measureText } from "@remotion/layout-utils";import {loadFont ,fontFamily } from "@remotion/google-fonts/Inter";const {waitUntilDone } =loadFont ("normal");constMyComp :React .FC = () => {const [dimensions ,setDimensions ] =useState <Dimensions | null>(null);useEffect (() => {// Wait until the font is loaded before measuring textwaitUntilDone ().then (() => {constmeasurement =measureText ({fontFamily :fontFamily ,fontSize : 14,fontWeight : "400",text : "Hello world",});// We don't need to use delayRender() here, because// font loading from @remotion/google-fonts is already wrapped in itsetDimensions (measurement );});}, []);return null;};
MyComp.tsxtsximport {useState ,useEffect } from "react";import {Dimensions ,measureText } from "@remotion/layout-utils";import {loadFont ,fontFamily } from "@remotion/google-fonts/Inter";const {waitUntilDone } =loadFont ("normal");constMyComp :React .FC = () => {const [dimensions ,setDimensions ] =useState <Dimensions | null>(null);useEffect (() => {// Wait until the font is loaded before measuring textwaitUntilDone ().then (() => {constmeasurement =measureText ({fontFamily :fontFamily ,fontSize : 14,fontWeight : "400",text : "Hello world",});// We don't need to use delayRender() here, because// font loading from @remotion/google-fonts is already wrapped in itsetDimensions (measurement );});}, []);return null;};
Use the validateFontIsLoaded optionv4.0.136
Pass validateFontIsLoaded: true to any of measureText(), fitText(), and fillTextBox() to validate that the font family you passed is actually loaded.
This will take a second measurement with the fallback font and if it produces the same measurements, it assumes the fallback font was used and will throw an error.
In Remotion v5, this will become the default.
Match all font properties
When measuring text, ensure that all font properties match the ones you are going to use in your video.
This includes fontFamily, fontSize, and fontWeight, letterSpacing and fontVariantNumeric.
You could make reusable variables that you reference in both the measuring function and the actual component.
Using variables for font propertiestsximport {measureText } from "@remotion/layout-utils";consttext = "Hello world";constfontFamily = "Inter";constfontWeight = "bold";constfontSize = 16;// Use the variable in the measurement function:measureText ({text ,fontFamily ,fontWeight ,fontSize ,});// As well as in markup<div style ={{fontFamily ,fontWeight ,fontSize }}>{text }</div >;
Using variables for font propertiestsximport {measureText } from "@remotion/layout-utils";consttext = "Hello world";constfontFamily = "Inter";constfontWeight = "bold";constfontSize = 16;// Use the variable in the measurement function:measureText ({text ,fontFamily ,fontWeight ,fontSize ,});// As well as in markup<div style ={{fontFamily ,fontWeight ,fontSize }}>{text }</div >;
Be aware of borders and padding
Adding a padding or a border to a word will skew the measurements.
Avoid using padding altogether and use the natural spacing between words.
Instead of border, use an outline to add a line outside the text without affecting its layout.
Whitespace
When measuring, the Layout utils will wrap the text in a <span> with display: inline-block and white-space: pre applied.
This will also measure the width of the whitespace characters.
Add those two CSS properties to your markup as well to match it with the measurements.
Server-side rendering
The layout utilities need to be run in a browser.
If you are using them in a component that will be server-side rendered, then we recommend you call the functions in a useEffect, like on the first example on this page.