Creating & Styling Custom Components

As with most development, there are many ways for you to approach your customizations on top of Flex. These guidelines are based on our experience building Flex Plugins.

Custom Components

When building a new component, we recommend following the conventions demoed by the Plugin Builder. Create a directory within /src/components, and then a trio of files to represent the content and styles of your component.

├── components
│   └── MyComponent
│   │   └── MyComponent.jsx
│   │   └── MyComponent.Container.js
│   │   └── MyComponent.Styles.js

In this example:

  • MyComponent.jsx will return a React component that could be added by one of Flex's Content.add() APIs
  • MyComponent.Container.js connects the presentational component (MyComponent.jsx) to the Redux store
  • MyComponent.Styles.js manages the styles you will apply to your component and its children

Using Material-UI

Not every component you build needs to start from scratch. Existing React component libraries can help you use components that have already been built with browser compatibility, responsive screen sizes, and accessibility in mind. Internally, flex-ui leverages material-ui v3.9.3 for many of its components. You can similarly use Material-UI v3.9.3 to create components that start with a similar style to Flex's existing layout.

Although material-ui is already a dependency of flex-ui, we recommend including this as an explicit dependency in your plugin project's package.json. You would add this within your dependencies:

// package.json

"dependencies": {
    "@material-ui/core": "^3.9.3",

Styling Components

We've found it easier to manage plugin development when your styles and your code are bundled together as part of your plugin. We recommend using Emotion for managing the styles of your custom components. If you choose to use Emotion, make sure to include it with your package.json dependencies.


We suggest defining a component-level style wrapper for each of your components. However, if the same styles are applied on the same type of element or you want to do dynamic styling, create separate styled components for better reusability.

Following the file structure above, we recommend keeping your styles alongside your components in files such as MyComponent.Styles.js.

Using Emotion

There are many ways you can use Emotion to style your components. We suggest using styled to define a component-level style wrapper. This styled component will include all of the styles for your main component and its children.

// Panel.ts
import React from 'react';
import { PanelStyles } from './Panel.Styles';

const Panel = () => {
 return (
       <li className="first-item">A</li>
       <li className="second-item">B</li>
       <li className="third-item">C</li>

export default Panel;

// Panel.Styles.ts
import styled from 'react-emotion';

export const PanelStyles = styled('div')`
   text-align: center;
   background: #D8BFD8;
   color: #fff;
   height: 100%;

   ul {
       Padding-top: 10px;
   .first-item {
       font-size: 30px;
   .second-item {
       font-size: 40px;
   .third-item {
       font-size: 50px;

This approach also introduces useful conventions:

  • Using classnames over individually styled elements favors using HTML elements whose semantics are clearer and more familiar to developers
  • When an element has a classname, it’s easy to infer that it is only styled with CSS and there is no custom functionality.

Applying Dynamic Styles

styled can also be used to implement dynamic styles based on props. The Flex theme is automatically accessible within styled components via props.theme because Flex UI wraps all of its components in a ThemeProvider. You can also use this approach to pass in custom props, like bgColor in the example below.

// MyView.Styles.ts
import styled from 'react-emotion'

export const SubHeader = styled('div')<{ bgColor: string }>`
    color: ${props => props.theme.colors.base1};
    background-color: ${props => props.bgColor};
    font-weight: bold;
    text-transform: uppercase;

// MyView.tsx
render() {
    return (
            <SubHeader bgColor="red">This font color should be red.</SubHeader>
            <SubHeader bgColor="blue">This font color should be blue.</SubHeader>

Global Styles

To add global styles to your plugin, use injectGlobal from Emotion. We suggest keeping a separate file for your global styles and importing it in your top-level plugin.

// GlobalStyles.ts
import { injectGlobal } from 'react-emotion';

   .block {
       display: block;
   .inline-block {
       display: inline-block;

// MyPlugin.tsx
import '../common/GlobalStyles.ts

Using a CSS file with your plugin

You can also declare your styles in a CSS file and import that into a JS file for your global styles.

// GlobalStyles.js
import { injectGlobal } from 'react-emotion';
import global from './global.css';
/* global.css */
.Twilio-SidePanel-Custom-Container {
  height: 100%;
  border: 1px blue;

You can then use displayName to load a stock Flex component (like the SidePanel) and dynamically set its CSS class name based on the string that you set.

        themeOverride={theme && theme.OutboundDialerPanel}

In this example, the styles you've declared within .Twilio-SidePanel-Custom-Container in your CSS file will be applied.

External Styles

It may not always be practical to define your styles alongside each component. Maybe you are using shared stylesheets across a suite of applications. Or maybe you're buiding multiple plugins that should share a central CSS asset.

The loadCSS and loadJS methods from flex-plugin can be used in these situations to load external resources when initializing your plugin.

import { FlexPlugin, loadCSS, loadJS } from 'flex-plugin';

export default class AdminPlugin extends FlexPlugin {
   constructor() {

   public init(flex, manager) {

One difficulty with this approach is ensuring that your external URLs can be used in whichever environment you're deploying your plugin. For example, you wouldn't want to re-build your plugin if the styles depend on versioned URLs or if the assets are different in your development vs. production environment.

One approach is to use the Flex Configuration API to store the URLs as attributes, and then to reference these attributes from within your plugin.

curl -X POST -u ACxxx:auth_token \
    -H 'Content-Type: application/json' \
    -d '{
        "account_sid": "ACxxx",
        "attributes": {
            "stylesheet_url": ""
public init(flex, manager) {

Rate this page:

Need some help?

We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd by visiting Twilio's Community Forums or browsing the Twilio tag on Stack Overflow.

Thank you for your feedback!

We are always striving to improve our documentation quality, and your feedback is valuable to us. How could this documentation serve you better?

Sending your feedback...
🎉 Thank you for your feedback!
Something went wrong. Please try again.

Thanks for your feedback!

Refer us and get $10 in 3 simple steps!

Step 1

Get link

Get a free personal referral link here

Step 2

Give $10

Your user signs up and upgrade using link

Step 3

Get $10

1,250 free SMSes
OR 1,000 free voice mins
OR 12,000 chats
OR more