---
title: Add Custom Fonts
product: Survey Creator
description: Theme Editor is a form styling tool integrated into SurveyJS Form Builder. With the Theme Editor, form creators can use a set of UI controls to adjust form colors, fonts, sizes, and more. If a desired font is missing from the predefined font collection, you can easily register a custom font and make it available in the font families list. Try out a live demo for JavaScript with a step-by-step guide on how to add and use custom fonts in SurveyJS Form Builder.
framework: React
source: https://surveyjs.io/survey-creator/examples/add-custom-fonts/reactjs
index: https://surveyjs.io/survey-creator/examples/overview.md
---

# Add Custom Fonts (React)

Theme Editor in SurveyJS Form Builder enables designers to personalize surveys and forms by creating custom UI themes. Although Theme Editor ships with a set of default fonts, you might want to use custom branded fonts to enhance the look and feel of your forms and give your surveys a personalized touch. To add custom fonts to Theme Editor, follow these steps:

1. Register custom fonts.      
Add custom fonts to the page with Survey Creator. In this demo, custom fonts are loaded from a server and added as a `<style>` element to the `<head>` of the page. Refer to the `loadFont` function for code listing. The following code shows how you can specify custom TTF fonts using CSS:

    ```css
    @font-face {
      font-family: "RobotoMono-Regular"; /* Provide a name for your font */
      src: url("./custom-fonts/RobotoMono-Regular.ttf") format("truetype");
      /* Add other font properties, like `font-weight` and `font-style` if needed */
    }
    @font-face {
      font-family: "RobotoMono-Italic"; /* Provide a name for your font */
      src: url("./custom-fonts/RobotoMono-Italic.ttf") format("truetype");
      /* Add other font properties, like `font-weight` and `font-style` if needed */
    }
    ```

1. Add custom fonts to the font list.      
Import the `DefaultFonts` array from the `"survey-creator-core"` module and push new font names to this array. The font names must begin with a font's `font-family` attribute value:

    ```js
    import { DefaultFonts } from "survey-creator-core";

    DefaultFonts.push(
        "RobotoMono-Regular, monospace",
        "RobotoMono-Italic, monospace"
    );
    ```

Now, custom fonts are available within Theme Editor. For instance, you can apply them using the **Font Family** setting in the **Appearance** tab:

<img src="/Content/Images/examples/custom-fonts/custom-fonts.png" alt="Access custom fonts in SurveyJS Theme Editor" width="1600" height="782">

## Files

### `public/index.html`

```html
<!-- Uncomment the following lines to enable Ace Editor in the JSON Editor tab -->
<!-- 
<script src="https://unpkg.com/ace-builds/src-min-noconflict/ace.js"></script>
<script src="https://unpkg.com/ace-builds/src-min-noconflict/ext-searchbox.js"></script>
<script src="https://unpkg.com/ace-builds/src-min-noconflict/theme-clouds_midnight.js"></script>
-->

<div id="surveyCreatorContainer" style="position: absolute; height: 100%; width: 100%"></div>
```

### `src/survey_json.js`

```js
export const formJSON = {
  "title": "Online Check-in",
  "description": "Check-in is available 2 to 24 hours prior to departure for all destinations. To complete the check-in process, please fill out the form below.",
  "completedHtml": "<div style=\"max-width:640px;text-align:center;margin:16px auto;\">\n\n<div style=\"padding:0 24px;\">\n<h4>Check-in complete.</h4>\n<p>Thank you for checking in. Your journey with us is all set. Have a great flight.</p>\n</div>\n\n</div>\n",
  "pages": [
    {
      "name": "page1",
      "elements": [
        {
          "type": "paneldynamic",
          "name": "passengers",
          "width": "100%",
          "minWidth": "256px",
          "titleLocation": "hidden",
          "templateElements": [
            {
              "type": "text",
              "name": "first-name",
              "width": "35%",
              "minWidth": "208px",
              "title": "PASSENGER #{panelIndex} INFO",
              "titleLocation": "top",
              "placeholder": "First name"
            },
            {
              "type": "text",
              "name": "last-name",
              "width": "30%",
              "minWidth": "172px",
              "startWithNewLine": false,
              "title": " ",
              "titleLocation": "top",
              "placeholder": "Last name"
            },
            {
              "type": "dropdown",
              "name": "prefix",
              "width": "35%",
              "minWidth": "208px",
              "startWithNewLine": false,
              "title": " ",
              "titleLocation": "top",
              "choices": [
                "Mr.",
                "Mrs.",
                "Ms."
              ],
              "choicesOrder": "random",
              "placeholder": "Prefix",
              "allowClear": false
            },
            {
              "type": "multipletext",
              "name": "birthdate",
              "width": "65%",
              "minWidth": "256px",
              "items": [
                {
                  "name": "date",
                  "inputType": "date",
                  "title": "Date of birth"
                }
              ]
            },
            {
              "type": "text",
              "name": "nationality",
              "width": "35%",
              "minWidth": "208px",
              "startWithNewLine": false,
              "placeholder": "Nationality"
            },
            {
              "type": "text",
              "name": "passport-number",
              "width": "100%",
              "minWidth": "256px",
              "title": "PASSENGER #{panelIndex} ID",
              "titleLocation": "top",
              "placeholder": "Passport #"
            },
            {
              "type": "dropdown",
              "name": "passport-issue-country",
              "width": "35%",
              "minWidth": "208px",
              "choicesByUrl": {
                "url": "https://surveyjs.io/api/CountriesExample",
                "valueName": "name"
              },
              "placeholder": "Country of issue",
              "allowClear": false
            },
            {
              "type": "multipletext",
              "name": "passport-exp-date",
              "width": "65%",
              "minWidth": "256px",
              "startWithNewLine": false,
              "items": [
                {
                  "name": "date",
                  "inputType": "date",
                  "title": "Exp. date"
                }
              ]
            }
          ],
          "panelCount": 1,
          "minPanelCount": 1,
          "confirmDeleteText": "Do you want to delete the passenger?",
          "addPanelText": "ADD PASSENGER",
          "removePanelText": "REMOVE",
          "showProgressBar": false
        },
        {
          "type": "panel",
          "name": "person-to-notify",
          "elements": [
            {
              "type": "text",
              "name": "person-to-notify-first-name",
              "width": "35%",
              "minWidth": "208px",
              "title": "PERSON TO NOTIFY",
              "titleLocation": "top",
              "setValueIf": "{passengers[0].first-name} notempty",
              "setValueExpression": "{passengers[0].first-name}",
              "placeholder": "First name"
            },
            {
              "type": "text",
              "name": "person-to-notify-last-name",
              "width": "30%",
              "minWidth": "172px",
              "startWithNewLine": false,
              "title": " ",
              "titleLocation": "top",
              "setValueIf": "{passengers[0].last-name} notempty",
              "setValueExpression": "{passengers[0].last-name}",
              "placeholder": "Last name"
            },
            {
              "type": "dropdown",
              "name": "person-to-notify-prefix",
              "width": "35%",
              "minWidth": "208px",
              "startWithNewLine": false,
              "title": " ",
              "titleLocation": "top",
              "setValueIf": "{passengers[0].prefix} notempty",
              "setValueExpression": "{passengers[0].prefix}",
              "choices": [
                "Mr.",
                "Mrs.",
                "Ms."
              ],
              "choicesOrder": "random",
              "placeholder": "Prefix",
              "allowClear": false
            },
            {
              "type": "text",
              "name": "person-to-notify-email",
              "width": "65%",
              "minWidth": "256px",
              "inputType": "email",
              "placeholder": "Email"
            },
            {
              "type": "text",
              "name": "person-to-notify-phone",
              "width": "35%",
              "minWidth": "208px",
              "startWithNewLine": false,
              "placeholder": "Phone"
            },
            {
              "type": "text",
              "name": "person-to-notify-address",
              "width": "100%",
              "minWidth": "256px",
              "title": "ADDRESS",
              "titleLocation": "top",
              "placeholder": "Address line 1"
            },
            {
              "type": "text",
              "name": "person-to-notify-city",
              "width": "35%",
              "minWidth": "208px",
              "placeholder": "City"
            },
            {
              "type": "text",
              "name": "person-to-notify-state",
              "width": "30%",
              "minWidth": "172px",
              "startWithNewLine": false,
              "placeholder": "State"
            },
            {
              "type": "text",
              "name": "person-to-notify-zip",
              "width": "35%",
              "minWidth": "208px",
              "startWithNewLine": false,
              "placeholder": "Zip Code"
            },
            {
              "type": "dropdown",
              "name": "person-to-notify-country",
              "width": "100%",
              "minWidth": "256px",
              "choicesByUrl": {
                "url": "https://surveyjs.io/api/CountriesExample",
                "valueName": "name"
              },
              "placeholder": "Country",
              "allowClear": false
            }
          ],
          "questionTitleLocation": "hidden",
          "width": "100%",
          "minWidth": "256px"
        },
        {
          "type": "panel",
          "name": "flight",
          "elements": [
            {
              "type": "text",
              "name": "departure-booking-number",
              "width": "65%",
              "minWidth": "256px",
              "title": "DEPARTURE",
              "titleLocation": "top",
              "validators": [
                {
                  "type": "regex",
                  "text": "Your booking number must consist of exactly 6 digits.",
                  "regex": "^\\d{6}$"
                }
              ],
              "maxLength": 6,
              "placeholder": "Please enter your 6-digit booking number"
            },
            {
              "type": "text",
              "name": "departure-flight-number",
              "width": "35%",
              "minWidth": "208px",
              "startWithNewLine": false,
              "title": " ",
              "titleLocation": "top",
              "placeholder": "Flight #"
            },
            {
              "type": "multipletext",
              "name": "departure-date",
              "width": "65%",
              "minWidth": "256px",
              "items": [
                {
                  "name": "date",
                  "inputType": "date",
                  "title": "Date"
                }
              ]
            },
            {
              "type": "multipletext",
              "name": "departure-time",
              "width": "35%",
              "minWidth": "208px",
              "startWithNewLine": false,
              "items": [
                {
                  "name": "time",
                  "inputType": "time",
                  "title": "Time"
                }
              ]
            },
            {
              "type": "dropdown",
              "name": "departure-country",
              "width": "65%",
              "minWidth": "256px",
              "title": "DEPARTING FROM",
              "choicesByUrl": {
                "url": "https://surveyjs.io/api/CountriesExample"
              },
              "placeholder": "Country",
              "allowClear": false
            },
            {
              "type": "text",
              "name": "departure-city",
              "width": "35%",
              "minWidth": "208px",
              "startWithNewLine": false,
              "title": " ",
              "placeholder": "City"
            },
            {
              "type": "dropdown",
              "name": "destination-country",
              "width": "65%",
              "minWidth": "256px",
              "title": "DESTINATION",
              "titleLocation": "top",
              "choicesByUrl": {
                "url": "https://surveyjs.io/api/CountriesExample"
              },
              "placeholder": "Country",
              "allowClear": false
            },
            {
              "type": "text",
              "name": "destination-city",
              "width": "35%",
              "minWidth": "208px",
              "startWithNewLine": false,
              "title": " ",
              "titleLocation": "top",
              "placeholder": "City"
            },
            {
              "type": "checkbox",
              "name": "connecting-flight",
              "width": "100%",
              "minWidth": "256px",
              "choices": [
                {
                  "value": "true",
                  "text": "I have a connecting flight"
                }
              ]
            },
            {
              "type": "multipletext",
              "name": "connecting-flight-date",
              "visibleIf": "{connecting-flight} = ['true']",
              "width": "65%",
              "minWidth": "256px",
              "items": [
                {
                  "name": "date",
                  "inputType": "date",
                  "title": "Date"
                }
              ]
            },
            {
              "type": "multipletext",
              "name": "connecting-flight-time",
              "visibleIf": "{connecting-flight} = ['true']",
              "width": "35%",
              "minWidth": "208px",
              "startWithNewLine": false,
              "items": [
                {
                  "name": "time",
                  "inputType": "time",
                  "title": "Time"
                }
              ]
            },
            {
              "type": "text",
              "name": "connecting-flight-booking-number",
              "visibleIf": "{connecting-flight} = ['true']",
              "width": "65%",
              "minWidth": "256px",
              "title": "DEPARTURE",
              "validators": [
                {
                  "type": "regex",
                  "text": "Your booking number must consist of exactly 6 digits.",
                  "regex": "^\\d{6}$"
                }
              ],
              "maxLength": 6,
              "placeholder": "Please enter your 6-digit booking number"
            },
            {
              "type": "text",
              "name": "connecting-flight-number",
              "visibleIf": "{connecting-flight} = ['true']",
              "width": "35%",
              "minWidth": "208px",
              "startWithNewLine": false,
              "placeholder": "Flight #"
            }
          ],
          "questionTitleLocation": "hidden",
          "width": "100%",
          "minWidth": "256px"
        }
      ]
    }
  ],
  "questionDescriptionLocation": "underInput",
  "questionErrorLocation": "bottom",
  "completeText": "Check In",
  "widthMode": "static",
  "width": "860"
}
```

### `src/theme_json.js`

```js
export const customTheme = {
    "backgroundImageFit": "cover",
    "backgroundImageAttachment": "scroll",
    "backgroundOpacity": 1,
    "cssVariables": {
        "--sjs2-color-bg-basic-primary": "rgba(255, 255, 255, 1)",
        "--sjs2-color-utility-property-grid": "rgba(255, 255, 255, 1)",
        "--sjs2-color-utility-tabs": "rgba(255, 255, 255, 1)",
        "--sjs2-color-utility-toolbox": "rgba(255, 255, 255, 1)",
        "--sjs2-color-bg-basic-primary-dim": "rgba(248, 248, 248, 1)",
        "--sjs2-color-bg-neutral-tertiary-dim": "rgba(243, 243, 243, 1)",
        "--sjs2-color-utility-surface-survey-panelless": "rgba(243, 243, 243, 1)",
        "--sjs2-color-utility-surface-survey": "rgba(243, 243, 243, 1)",
        "--sjs2-color-bg-basic-secondary": "rgba(249, 249, 249, 1)",
        "--sjs2-color-bg-basic-secondary-dim": "rgba(243, 243, 243, 1)",
        "--sjs2-color-fg-basic-primary": "rgba(0, 0, 0, 0.91)",
        "--sjs2-color-fg-basic-secondary": "rgba(0, 0, 0, 0.45)",
        "--sjs2-color-project-brand-600": "rgba(25, 179, 148, 1)",
        "--sjs2-color-bg-brand-secondary": "rgba(25, 179, 148, 0.1)",
        "--sjs2-color-bg-brand-primary-dim": "rgba(20, 164, 139, 1)",
        "--sjs2-color-fg-brand-on-primary": "rgba(255, 255, 255, 1)",
        "--sjs2-color-fg-brand-primary-disabled": "rgba(255, 255, 255, 0.25)",
        "--sjs2-base-unit-size": "8px",
        "--sjs2-base-unit-spacing": "8px",
        "--sjs2-base-unit-radius": "4px",
        "--sjs2-color-bg-accent-primary": "rgba(255, 152, 20, 1)",
        "--sjs2-color-bg-accent-secondary": "rgba(255, 152, 20, 0.1)",
        "--sjs2-color-bg-accent-secondary-dim": "rgba(255, 152, 20, 0.25)",
        "--sjs2-color-fg-accent-on-primary": "rgba(255, 255, 255, 1)",
        "--sjs2-color-fg-accent-primary-disabled": "rgba(255, 255, 255, 0.25)",
        "--sjs2-border-effect-surface-default": "0px 1px 2px 0px rgba(0, 0, 0, 0.15)",
        "--sjs2-border-effect-floating-default": "0px 2px 6px 0px rgba(0, 0, 0, 0.1),0px 8px 16px 0px rgba(0, 0, 0, 0.1)",
        "--sjs2-border-effect-component-formbox-default": "inset 0px 1px 2px 0px rgba(0, 0, 0, 0.15)",
        "--sjs2-border-effect-component-check-true-default": "inset 0px 1px 2px 0px rgba(0, 0, 0, 0.15)",
        "--sjs2-border-effect-component-check-false-default": "inset 0px 1px 2px 0px rgba(0, 0, 0, 0.15)",
        "--sjs2-color-border-basic-secondary": "rgba(0, 0, 0, 0.09)",
        "--sjs2-color-component-input-default-line": "rgba(0, 0, 0, 0.16)",
        "--sjs2-color-border-basic-secondary-overlay": "rgba(0, 0, 0, 0.16)",
        "--sjs2-color-bg-alert-primary": "rgba(229, 10, 62, 1)",
        "--sjs2-color-bg-alert-secondary": "rgba(229, 10, 62, 0.1)",
        "--sjs2-color-fg-alert-on-primary": "rgba(255, 255, 255, 1)",
        "--sjs2-color-bg-positive-primary": "rgba(25, 179, 148, 1)",
        "--sjs2-color-bg-positive-secondary": "rgba(25, 179, 148, 0.1)",
        "--sjs2-color-fg-positive-on-primary": "rgba(255, 255, 255, 1)",
        "--sjs2-color-bg-note-primary": "rgba(67, 127, 217, 1)",
        "--sjs2-color-bg-note-secondary": "rgba(67, 127, 217, 0.1)",
        "--sjs2-color-fg-note-on-primary": "rgba(255, 255, 255, 1)",
        "--sjs2-color-bg-warning-primary": "rgba(255, 152, 20, 1)",
        "--sjs2-color-bg-warning-secondary": "rgba(255, 152, 20, 0.1)",
        "--sjs2-color-fg-warning-on-primary": "rgba(255, 255, 255, 1)",
        "--sjs2-typography-font-family-text": "RobotoMono-Regular, monospace",
        "--sjs2-typography-font-weight-component-header-title": "700",
        "--sjs2-typography-font-size-component-header-description": "20px",
        "--sjs2-typography-font-weight-component-page-title": "700"
    },
    "themeName": "default",
    "colorPalette": "light",
    "isPanelless": false
};
```

### `src/SurveyCreatorComponent.jsx`

```js
import React from "react";
import { SurveyCreator, SurveyCreatorComponent } from "survey-creator-react";
import "survey-core/survey.i18n";
import "survey-creator-core/survey-creator-core.i18n";
import { formJSON } from "./survey_json";
import { customTheme } from "./theme_json";
import { DefaultFonts } from "survey-creator-core";

import "survey-core/survey-core.css";
import "survey-creator-core/survey-creator-core.css";
import "./index.css";

import SurveyTheme from "survey-core/themes";
import { registerCreatorTheme, registerSurveyTheme } from "survey-creator-core";

registerSurveyTheme(SurveyTheme); // Add predefined Form Library UI themes
registerCreatorTheme(SurveyTheme); // Add predefined Survey Creator UI themes

let fontIsLoading = true;
let serverHost = window.location.origin;
if (serverHost.indexOf("localhost") < 0 && serverHost.indexOf("surveyjs") < 0)
    serverHost = "https://surveyjs.io";

loadFont({
    serverHost: serverHost,
    fontPath: "fontbase64_robotomonoregular",
    fontFamily: "RobotoMono-Regular"
});

loadFont({
    serverHost: serverHost,
    fontPath: "fontbase64_robotomonoitalic",
    fontFamily: "RobotoMono-Italic"
});

function loadFont({ serverHost, fontPath, fontFamily }) { 
    const fontUrl = serverHost + "/api/" + fontPath;
    fetch(fontUrl)
        .then(response => {
            if (!response.ok) {
                throw new Error(`HTTP error: ${response.status}`);
            }
            return response.text();
        })
        .then(base64Font => {
            // Create a `<style>` element for the loaded font
            var style = document.createElement('style');

            // Set the `innerHTML` aatribute of the `<style>` element
            // to the `@font-face` rule with base64-encoded font data
            style.innerHTML = "@font-face { font-family: '" + fontFamily + "'; src: url(data:application/x-font-woff;charset=utf-8;base64," + base64Font + ") format('truetype'); }";

            // Append the `<style>` element to the document `<head>`
            document.head.appendChild(style);
            fontIsLoading = false;
        });
};

function SurveyCreatorRenderComponent() {
    const creator = new SurveyCreator({ showThemeTab: true });
    DefaultFonts.push(
        "RobotoMono-Regular, monospace",
        "RobotoMono-Italic, monospace"
    );
    
    creator.JSON = formJSON;
    creator.theme = customTheme;
    creator.activeTab = "theme";
    return (<SurveyCreatorComponent creator={creator} />);
}

export default SurveyCreatorRenderComponent;
```

### `src/index.css`

```css
/* You can add your custom CSS here. */
```

### `src/index.js`

```js
import React from "react";
import { createRoot } from "react-dom/client";
import SurveyCreatorRenderComponent from "./SurveyCreatorComponent";

const root = createRoot(document.getElementById("surveyCreatorContainer"));
root.render(<SurveyCreatorRenderComponent />);
```

### `package.json`

```json
{
  "dependencies": {
    "react": "latest",
    "react-dom": "latest",
    "survey-core": "latest",
    "survey-react-ui": "latest",
    "survey-creator-core": "latest",
    "survey-creator-react": "latest"
  },
  "devDependencies": {
    "react-scripts": "latest"
  }
}
```

## Other Frameworks

- [Angular](https://surveyjs.io/survey-creator/examples/add-custom-fonts/angular.md)
- [Vue 3](https://surveyjs.io/survey-creator/examples/add-custom-fonts/vue3js.md)
- [jQuery](https://surveyjs.io/survey-creator/examples/add-custom-fonts/jquery.md)
- [Vanilla JS](https://surveyjs.io/survey-creator/examples/add-custom-fonts/vanillajs.md)
