Custom Fonts
DivKit allows you to use custom fonts in your application. This makes it possible to maintain a consistent text style across all platforms and ensure compliance with your application's design.
General Concept
To use custom fonts in DivKit, you need to:
- Add fonts to your application resources
- Implement a font provider for the corresponding platform
- Pass the font provider to DivKit during initialization
- Use font names in DivKit JSON markup
In DivKit JSON markup, fonts are specified in the font_family
parameter of the div-text element:
Sample code
{
"type": "text",
"font_family": "MyCustomFont",
"font_weight": 500,
"text": "Text with custom font"
}
The font_weight
parameter defines the font thickness and can take the following values:
- 100 - Thin
- 200 - Extra Light
- 300 - Light
- 400 - Regular (default value)
- 500 - Medium
- 600 - Semi Bold
- 700 - Bold
- 800 - Extra Bold
- 900 - Black
Android
On the Android platform, to use custom fonts, you need to implement the DivTypefaceProvider
interface.
DivTypefaceProvider Implementation
import android.content.Context;
import android.graphics.Typeface;
import androidx.annotation.Nullable;
import com.yandex.div.core.font.DivTypefaceProvider;
public class CustomTypefaceProvider implements DivTypefaceProvider {
private final Context context;
// Cache fonts to improve performance
private Typeface regularTypeface;
private Typeface mediumTypeface;
private Typeface lightTypeface;
private Typeface boldTypeface;
public CustomTypefaceProvider(Context context) {
this.context = context;
}
@Nullable
@Override
public Typeface getRegular() {
if (regularTypeface == null) {
regularTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/MyFont-Regular.ttf");
}
return regularTypeface;
}
@Nullable
@Override
public Typeface getMedium() {
if (mediumTypeface == null) {
mediumTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/MyFont-Medium.ttf");
}
return mediumTypeface;
}
@Nullable
@Override
public Typeface getLight() {
if (lightTypeface == null) {
lightTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/MyFont-Light.ttf");
}
return lightTypeface;
}
@Nullable
@Override
public Typeface getBold() {
if (boldTypeface == null) {
boldTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/MyFont-Bold.ttf");
}
return boldTypeface;
}
// Optional: override the getTypefaceFor method for more precise control
// over font weight matching
@Nullable
@Override
public Typeface getTypefaceFor(int weight) {
if (weight >= 0 && weight < 350) {
return getLight();
} else if (weight >= 350 && weight < 450) {
return getRegular();
} else if (weight >= 450 && weight < 650) {
return getMedium();
} else {
return getBold();
}
}
}
Integration into Application
import com.yandex.div.core.Div2Context;
import com.yandex.div.core.DivConfiguration;
// When initializing DivKit
DivConfiguration configuration = new DivConfiguration.Builder()
.typefaceProvider(new CustomTypefaceProvider(context))
// other settings
.build();
Div2Context div2Context = Div2Context.create(
context,
configuration
);
iOS
On the iOS platform, to use custom fonts, you need to implement the DivFontProvider
protocol.
Adding Fonts to the Project
- Add font files (.ttf or .otf) to your project
- Make sure the fonts are included in the application resources (Bundle Resources)
- Add font information to Info.plist in the
Fonts provided by application
section:
<key>UIAppFonts</key>
<array>
<string>MyFont-Regular.ttf</string>
<string>MyFont-Medium.ttf</string>
<string>MyFont-Light.ttf</string>
<string>MyFont-Bold.ttf</string>
</array>
DivFontProvider Implementation
import UIKit
import DivKit
import VGSL
class CustomFontProvider: DivFontProvider {
func font(family: String, weight: DivFontWeight, size: CGFloat) -> Font {
// If a specific font family is specified
if family == "MyCustomFont" {
let fontName: String
switch weight {
case .light:
fontName = "MyFont-Light"
case .regular:
fontName = "MyFont-Regular"
case .medium:
fontName = "MyFont-Medium"
case .bold:
fontName = "MyFont-Bold"
}
if let font = UIFont(name: fontName, size: size) {
return Font(uiFont: font)
}
}
// Return system font if custom font is not found
let uiFont: UIFont
switch weight {
case .light:
uiFont = UIFont.systemFont(ofSize: size, weight: .light)
case .regular:
uiFont = UIFont.systemFont(ofSize: size, weight: .regular)
case .medium:
uiFont = UIFont.systemFont(ofSize: size, weight: .medium)
case .bold:
uiFont = UIFont.systemFont(ofSize: size, weight: .bold)
}
return Font(uiFont: uiFont)
}
// The method for getting a font by numerical weight is already implemented in the protocol extension
}
Integration into Application
import DivKit
// When initializing DivKit
let components = DivKitComponents(
divCustomBlockFactory: nil,
fontProvider: CustomFontProvider(),
// other parameters
)
Web
On the Web platform, to use custom fonts, you need to:
- Connect fonts using standard CSS methods (via
@font-face
or external services) - Use the
typefaceProvider
parameter when initializing DivKit
Connecting Fonts via CSS
The font family in CSS does not have to match the name in JSON.
Don't forget to provide all the styles and weights options that you will need in your markup (in this example, 400, 500, and 700 are added). Another option is to use variable fonts.
@font-face {
font-family: 'MyCustomFont';
src: url('fonts/MyFont-Regular.woff2') format('woff2'),
url('fonts/MyFont-Regular.woff') format('woff');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'MyCustomFont';
src: url('fonts/MyFont-Medium.woff2') format('woff2'),
url('fonts/MyFont-Medium.woff') format('woff');
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: 'MyCustomFont';
src: url('fonts/MyFont-Bold.woff2') format('woff2'),
url('fonts/MyFont-Bold.woff') format('woff');
font-weight: 700;
font-style: normal;
}
Using typefaceProvider
import { render } from '@divkitframework/divkit/client';
render({
id: 'my-divkit-container',
target: document.querySelector('#root'),
json: {
card: {
log_id: 'custom_fonts_example',
states: [{
state_id: 0,
div: {
type: 'text',
font_family: 'MyCustomFont',
font_weight: 500,
text: 'Text with custom font'
}
}]
}
},
typefaceProvider: (fontFamily, opts) => {
// You can implement mapping of font names from JSON to CSS
if (fontFamily === 'MyCustomFont') {
return 'MyCustomFont, sans-serif';
}
// For the default option, you can return an empty string.
return '';
}
});
Usage Examples in JSON
Basic Example
Sample code
{
"type": "text",
"font_family": "MyCustomFont",
"font_weight": 400,
"text": "Text with custom font"
}
Different Font Styles
Sample code
{
"type": "container",
"items": [
{
"type": "text",
"font_family": "MyCustomFont",
"font_weight": 300,
"text": "Text with light font (Light)"
},
{
"type": "text",
"font_family": "MyCustomFont",
"font_weight": 400,
"text": "Text with regular font (Regular)"
},
{
"type": "text",
"font_family": "MyCustomFont",
"font_weight": 500,
"text": "Text with medium font (Medium)"
},
{
"type": "text",
"font_family": "MyCustomFont",
"font_weight": 700,
"text": "Text with bold font (Bold)"
}
]
}
Using in Templates
Sample code
{
"templates": {
"title": {
"type": "text",
"font_family": "MyCustomFont",
"font_weight": 700,
"font_size": 20,
"$text": "title"
},
"body": {
"type": "text",
"font_family": "MyCustomFont",
"font_weight": 400,
"font_size": 16,
"$text": "text"
}
},
"card": {
"log_id": "custom_fonts_example",
"states": [
{
"state_id": 0,
"div": {
"type": "container",
"items": [
{
"type": "title",
"text": "Heading with custom font"
},
{
"type": "body",
"text": "Body text with custom font"
}
]
}
}
]
}
}
Recommendations
- Performance Optimization: Cache font instances to avoid reloading.
- Support for Different Weights: Implement support for different font weights to ensure design flexibility.
- Fallback Options: Always provide fallback font options in case the custom font fails to load.
- Font Preloading: For the web platform, it is recommended to preload fonts to avoid text flickering when the page loads.
- Testing: Check font rendering on various devices and under different conditions to ensure correct display.
Learn more
Follow DivKit news in the Telegram channel: http://t.me/divkit_news
You can also discuss topics of interest in the DivKit user community in Telegram: https://t.me/divkit_community_ru