Theme config
March 27, 2026 ยท View on GitHub
The ThemeContextProvider component receives a theme prop where you can customize some aspects of the lib.
The theme prop must have the following type:
type ThemeConfig = {
skin: Skin;
colorScheme?: ColorScheme;
i18n: {
locale: Locale;
phoneNumberFormattingRegionCode: RegionCode;
};
platformOverrides?: {
platform?: 'ios' | 'android';
insideNovumNativeApp?: boolean;
userAgent?: string;
};
texts?: Partial<Dictionary>;
analytics?: {
logEvent: (event: TrackingEvent) => Promise<void>;
};
Link?: LinkComponent;
useHrefDecorator: () => (href: string) => string;
preventCopyInFormFields?: boolean;
};
Only skin and i18n are mandatory.
Here is a description of every attribute:
skin: determines the look and feel used by the lib (colors, font weight, etc). You can usegetMovistarSkin,getVivoSkinto use a specific skin orgetSkinByName. You can also create your own custom skin.colorScheme: used to enable/disable the dark mode support. It can be'light'(force light mode),'dark'(force dark mode), or'auto'(uses OS/browser settings, this is the default behavior). We recommend using the default setting ('auto') if you want to support dark mode in your app.i18n: we use this to localize some messages or formatting dates phone numbers, etc.locale: a valid locale (language and region codes separated by'-'). For example'es-ES'.phoneNumberFormattingRegionCode: region code used to format phone numbers (for example inPhoneNumberField).
platformOverrides?:platform?: the lib applies some style differences depending on the current platform.@telefonica/misticawill try to automatically detect the platform, but you can manually set this setting to'ios'or'android'insideNovumNativeApp?:some components have different behavior if the web is running inside a webview in the native Novum App. The lib can autodetect it, but you can force it by setting this totrue.userAgent:IMPORTANT In case you are using SSR, you should set this value with the user-agent header you receive on every request to your server, otherwise the server-side render won't take the user agent into account.
texts?: some copies you can customize. See texts doc.t: this is the translate funtion. It accepts a token as exported bytextTokens. See texts doc.analytics?: see analytics docs.Link?: theLinkcomponent you want to use by Touchables that use the propto. By default, the lib uses an anchor tag (<a>). Use this prop to use the Link component from ReactRouter, Next.js or any other library. Please read the LinkComponent section for more info.useHrefDecorator: it is a React hook that a function that takes ahrefand returns a newhref. This is useful to automatically add parameters to thehrefbeing used in Touchable components (for example, to add autm_sourceparameter to thehref).preventCopyInFormFields?: this is used as the default value forpreventCopyprop in form fields.falseby default.
LinkComponent
You can use a custom component or use a built in one. Mistica has built in support for: Next12, Next13,
Next14, ReactRouter5 and ReactRouter6.
Next example
import Link from 'next/link';
const theme: ThemeConfig = {
...
Link: {type: 'Next14', Component: Link}
}
React Router example
import {Link} from 'react-router-dom';
const theme: ThemeConfig = {
...
Link: {type: 'ReactRouter6', Component: Link}
}
Create a custom skin
If your app doesn't follow the branding of mistica builtin skins (Movistar, Vivo, O2, Telefonica, etc.), you
can still use mistica with your custom skin. Just import the Skin type and create a new skin config that
implements the Skin interface (you need to define all the required color constants):
If you need to customize default component colors, border radii, or similar visual tokens and there is no component prop for that, prefer a custom skin over ad hoc CSS/style overrides. You can:
- start from a built-in skin like
getMovistarNewSkin()and override the tokens you need - start from a built-in palette export like
movistarNewPalette - define your own palette/colors from scratch
import type {Skin} from '@telefonica/mistica';
const skin: Skin = {
name: 'your skin name',
colors: {
// define here the required color constants
},
darkModeColors: {
// optionally define here the color constant overrides for dark mode
},
};
<ThemeContextProvider
theme={{
skin,
i18n: {
locale: 'es-ES',
phoneNumberFormattingRegionCode: 'ES',
},
}}
>
<App />
</ThemeContextProvider>;
You can also extend an existing skin instead of defining everything from scratch:
import {getMovistarNewSkin, movistarNewPalette, type Skin} from '@telefonica/mistica';
const baseSkin = getMovistarNewSkin();
const palette = {
...movistarNewPalette,
brandPrimary: '#0050D8',
};
const skin: Skin = {
...baseSkin,
name: 'Acme',
colors: {
...baseSkin.colors,
brand: palette.brandPrimary,
backgroundBrand: palette.brandPrimary,
backgroundBrandTop: palette.brandPrimary,
backgroundBrandBottom: palette.blue800,
buttonPrimaryBackground: palette.brandPrimary,
buttonPrimaryBackgroundHover: palette.blue800,
buttonPrimaryBackgroundPressed: palette.blue800,
textButtonPrimary: palette.white,
},
};
If you also need different default radii, override borderRadii in the custom skin rather than setting
border radius ad hoc in component styles.
You can see an example in the examples folder.