Using Basecamp's Trix Editor in React ( Shopify Polaris )
Tags: javascript, react, webdev, shopify
Published: 2020-02-15 07:47:11

---
title: Using Basecamp's Trix Editor in React ( Shopify Polaris )
published: true
description: This post shows how to setup Trix Rich Text Editor by Basecamp in Shopify Polaris React components.
tags: javascript, react, webdev, shopify
---

This post was originally published on Medium. [Link](https://medium.com/@Zubairmohsin33/using-basecamps-trix-editor-in-react-shopify-polaris-9492fda22e73)

##The Need
I develop Shopify Apps as a Freelancer and Shopify has offered their own UI toolkit called **Polaris** which is highly recommended for building apps interfaces. 
They offer React Components and also HTML/CSS version of components. Sadly, there is no Rich Text Editor component in the toolkit as of now. Although, it's under consideration.

##Research
I did some research and found two options:
* TinyMCE
* Trix Editor
 

TinyMCE is feature rich and offers a lot, But I needed a simple one so I decided to go with Trix.

##Getting Started:
Pull in Trix using **npm**:
```javascript
npm install trix
```

Next, let's create a component named `wysiwyg.jsx` and use it in `App` component.
`App.js`
```javascript
import React, { Component } from "react";
import ReactDOM from "react-dom";
import {
    AppProvider,
    Page,
    Card,
    Layout,
} from "@shopify/polaris";
import Wysiwyg from "./components/wysiwyg";

export default class App extends React.Component {
  
  state = {
    content: ""
  }
    
  render(){
    return(
      <AppProvider apiKey={apiKey} shopOrigin={shopOrigin} forceRedirect={true}>
        <Page>
          <Layout>
            <Card>
                <Wysiwyg />
            </Card>
          </Layout>
         </Page>
      </AppProvider>
    );
  }
}
```
`wysiwyg.jsx`
```javascript
import React, { Component } from "react";
import Trix from "trix";

class Wysiwyg extends React.Component {

    render() {
        return (
            <div>
                <input
                    type="hidden"
                    id="trix"
                />
                <trix-editor input="trix" />
            </div>
        );
    }
}

export default Wysiwyg;
```
Trix editor stores its a content in a hidden element. ID property on that hidden element and input property on `trix-editor` must be same.

At this point you will see Trix working, if styles are not there, you can pull the stylesheet from CDN, or put a link tag. I am using `laravel-mix `so I imported the stylesheet in my `app.scss` like below:

```css
@import "~trix/dist/trix.css";
```
##Populating the stored content 😍
We can pass the data to component with **props**.
```javascript
<Wysiwyg value={this.state.content} />
```
and accepting this prop in the component as below:
```javascript
<input type="hidden" id="trix" value={this.props.value} />
```
##Updating the STATE 🤔
This is a little bit tricky. State is in the parent component and we need to tell the parent component that content of the editor is being changed.

Trix editor raises an event called `trix-change` [🔗](https://github.com/basecamp/trix#observing-editor-changes) . We can listen to this event and raise our own custom event.

Since `trix-editor` is in the DOM, we need **refs** to access it.

`wysiwyg.jsx`
```javascript
import React, { Component } from "react";
import Trix from "trix";

class Wysiwyg extends React.Component {
    constructor(props) {
        super(props);
        this.trixInput = React.createRef();
    }

    componentDidMount() {
        this.trixInput.current.addEventListener("trix-change", event => {
            console.log("trix change event fired");
            this.props.onChange(event.target.innerHTML); //calling custom event
        });
    }

    render() {
        return (
            <div>
                <input type="hidden" id="trix" value={this.props.value} />
                <trix-editor input="trix" ref={this.trixInput} />
            </div>
        );
    }
}

export default Wysiwyg;
```
Event handler on the parent component, via props as below:
`App.js`
```javascript
import React, { Component } from "react";
import ReactDOM from "react-dom";
import {
    AppProvider,
    Page,
    Card,
    Layout,
} from "@shopify/polaris";
import Wysiwyg from "./components/wysiwyg";

export default class App extends React.Component {
  
  state = {
    content: ""
  }
    
  render(){
    return(
      <AppProvider apiKey={apiKey} shopOrigin={shopOrigin} forceRedirect={true}>
        <Page>
          <Layout>
            <Card>
                <Wysiwyg onChange={this.handleContentChange} />
            </Card>
          </Layout>
         </Page>
      </AppProvider>
    );
  }


  handleContentChange = (content) => {
    this.setState({content : content});
  };
}
```
If you need multiple `wysiwyg` on same page, you can play around with passing props for **id** etc.

So, this is how you can use Trix Rich Text Editor in React and make it a reusable component.

This approach is heavily inspired by Laracast’s episode on Wysiwyg. [here](https://laracasts.com/series/lets-build-a-forum-with-laravel/episodes/99).

Happy coding 👨🏽‍💻