Skip to content

Instantly share code, notes, and snippets.

@jazzychad
Created June 2, 2025 19:30
Show Gist options
  • Save jazzychad/8ce63855296e29c5596163e6fceece82 to your computer and use it in GitHub Desktop.
Save jazzychad/8ce63855296e29c5596163e6fceece82 to your computer and use it in GitHub Desktop.
TRMNL plugin for RevenueCat
{
"title": "TRMNL plugin for RevenueCat",
"timestamp": "2025-06-02T19:30:16.469Z",
"visibility": "public",
"parts": [
{
"id": "D6H3-MxBeLuavHqIlJ5zI.md",
"timestamp": "2025-06-02T19:30:16.469Z",
"type": "post",
"subtype": "markdown"
}
]
}

Hi there.

This is how to create a RevenueCat plugin for TRMNL displays. Since it involves using RevenueCat API keys, I am not able to share the plugin as a recipe. I don't want to proxy your API keys through my server, nor should you want me to see your API keys or your financial information.

Step 1:

Go to your TRMNL dashboard and navigate to the Plugins section. Click "Private Plugin" and then click the "Add new" button

Step 2:

Set the Strategy to "Polling" and set the URL for your own backend endpoint.

Set the verb to GET.

Step 3:

Configure the UI.

Click the "Edit Markup" button.

For the "Full" variant, enter the following code:

<div class="layout layout--top layout--col" height="40px">
  <img class="img-dither" src="https://www.revenuecat.com/docs/img/logo-rc.svg" height="50" />
  <div><span class="label">Project : MyProject</span></div>
  <div class="layout layout--col stretch-x stretch-y">
    <div class="grid">
      <div class="item">
        <div class="meta"></div>
        <div class="content">
          <span class="value value--xlarge value--tnums" data-value-format="true">{{active_trials}}</span>
          <span class="label">Active Trials</span>
        </div>
      </div>
      <div class="item">
        <div class="meta"></div>
        <div class="content">
          <span class="value value--xlarge value--tnums" data-value-format="true">{{active_subs}}</span>
          <span class="label">Active Subscriptions</span>
        </div>
      </div>
    </div>

    <div class="w--full b-h-gray-5"></div>

    <div class="grid">
      <div class="col col--span-3 gap--medium">
        <div class="item">
          <div class="meta"></div>
          <div class="content">
            <span class="value value--tnums " data-value-format="true">${{mrr}}</span>
            <span class="label">MRR</span>
          </div>
        </div>

        <div class="w--full b-h-gray-5"></div>

        <div class="item">
          <div class="meta"></div>
          <div class="content">
            <span class="value value--tnums " data-value-format="true">${{p28}}</span>
            <span class="label">Last 28 Days</span>
          </div>
        </div>


      </div>

      <div class="col col--span-3 gap--medium">
        <div class="item">
          <div class="meta"></div>
          <div class="content">
            <span class="value value--tnums" data-value-format="true">{{new_customers}}</span>
            <span class="label">New Customers P28</span>
          </div>
        </div>

        <div class="w--full b-h-gray-5"></div>

        <div class="item">
          <div class="meta"></div>
          <div class="content">
            <span class="value value--tnums">{{active_users}}</span>
            <span class="label">Active Users P28</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

<div class="title_bar">
  <img class="image" src="https://usetrmnl.com/images/plugins/trmnl--render.svg">
  <span class="title">{{ trmnl.plugin_settings.instance_name }}</span>
  <span class="instance">RevenueCat Metrics</span>
</div>

For the "Half vertical" variant, enter the following code:

<div class="layout layout--top layout--col" height="30px">
  <img class="img-dither" src="https://www.revenuecat.com/docs/img/logo-rc.svg" height="25" />
  <div><span class="label">Project : MyProject</span></div>
  <div class="layout layout--col stretch-x stretch-y">
    <div class="grid">
      <div class="item">
        <div class="meta"></div>
        <div class="content">
          <span class="value value--tnums" data-value-format="true">{{active_trials}}</span>
          <span class="label small">Active Trials</span>
        </div>
      </div>
      <div class="item">
        <div class="meta"></div>
        <div class="content">
          <span class="value value--tnums" data-value-format="true">{{active_subs}}</span>
          <span class="label">Active Subs</span>
        </div>
      </div>
    </div>

    <div class="w--full b-h-gray-5"></div>

    <div class="grid">
      <div class="col col--span-3 gap--medium">
        <div class="item">
          <div class="meta"></div>
          <div class="content">
            <span class="value value--tnums " data-value-format="true">${{mrr}}</span>
            <span class="label">MRR</span>
          </div>
        </div>

        <div class="w--full b-h-gray-5"></div>

        <div class="item">
          <div class="meta"></div>
          <div class="content">
            <span class="value value--tnums" data-value-format="true">{{new_customers}}</span>
            <span class="label">New Cust P28</span>
          </div>
        </div>


      </div>

      <div class="col col--span-3 gap--medium">
        <div class="item">
          <div class="meta"></div>
          <div class="content">
            <span class="value value--tnums " data-value-format="true">${{p28}}</span>
            <span class="label">Last 28 Days</span>
          </div>
        </div>
        

        <div class="w--full b-h-gray-5"></div>

        <div class="item">
          <div class="meta"></div>
          <div class="content">
            <span class="value value--tnums">{{active_users}}</span>
            <span class="label">Active Users P28</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

<div class="title_bar">
  <img class="image" src="https://usetrmnl.com/images/plugins/trmnl--render.svg">
  <span class="title">{{ trmnl.plugin_settings.instance_name }}</span>
  <span class="instance">RevenueCat Metrics</span>
</div>

I currently don't have any layout code for the "Half horizontal" or "Quadrant" variants, but you could easily figure something out from the above layouts.

Step 4:

You will need to setup your backend server (or lambda function, or whatever kind of endpoint you want to configure). It's route should match the URL you entered into the plugin's Polling URL field.

This is an example of a node/js/ts/express server method to handle the call. It relies on having your RevenueCat API key and your project's API id. For maximum security these should be set as environment variables in whatever system you are using, but the actual implementation is up to you. The basic steps are to query the RevenueCat API "metrics/overview" endpoint and then parse through the results to return the data that TRMNL will display in the layout code.

Backend code example:

this.express.route('/revcat.json').get(async (req: express.Request, res: express.Response) => {
      const projectId = process.env.RC_PROJECTID
      const apiKey = process.env.RC_API_KEY

      const data = await fetch(`https://api.revenuecat.com/v2/projects/${projectId}/metrics/overview`, {
        headers: {
          Authorization: `Bearer ${apiKey}`,
          Accept: 'application/json',
        },
      })
      const obj = await data.json()
      function findValue(id: string): number {
        if (obj !== undefined && obj !== null) {
          for (const m of obj.metrics) {
            if (m.id === id) {
              return m.value
            }
          }
          return -1
        } else {
          return 0
        }
      }
      res.json({
        active_trials: findValue('active_trials'),
        active_subs: findValue('active_subscriptions'),
        mrr: findValue('mrr'),
        p28: findValue('revenue'),
        new_customers: findValue('new_customers'),
        active_users: findValue('active_users'),
      })
    })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment