> ## Content Index
> Fetch the complete content index at: https://tomblanchard.co.uk/llms.txt
> Use this file to discover other available public pages before exploring further.

# How I built Shopify Liquid REPL
- URL: https://tomblanchard.co.uk/how-i-built-shopify-liquid-repl/
- Published: 2018-05-21T12:42:29.000Z
- Updated: 2018-05-21T12:42:29.000Z
- Author: Tom Blanchard
- Tags: #Import 2026-10-26 21:01

I recently spent a couple of days building a tool in the form of a small web app [Shopify Liquid REPL](https://shopify-liquid-repl.tomblanchard.co.uk/?ref=tomblanchard.co.uk), it's similiar to the [Bable REPL](https://babeljs.io/repl/?ref=tomblanchard.co.uk), but it takes Shopify Liquid (different to [vanilla Liquid](https://github.com/Shopify/liquid?ref=tomblanchard.co.uk)) and outputs the compiled code.

I built this because I was tired of spinning up a new development shop/theme every time I wanted to simply test out the capabilities of Liquid, I used to rely on another tool named [DropPen](https://droppen.org/?ref=tomblanchard.co.uk) for this, but that seems to be broken nowadays.

I originally planned on using [Shopify/liquid](https://github.com/Shopify/liquid?ref=tomblanchard.co.uk) (what I call "vanilla Liquid") on my own server and handling the compiling through that, but there's quite a lot of differences between vanilla Liquid and the Liquid used on the actual Shopify servers. As stated [here](https://github.com/Shopify/slate/wiki/Local-development?ref=tomblanchard.co.uk), Shopify claim:

> Shopify Themes use [an extended version of Liquid](https://help.shopify.com/themes/liquid?ref=tomblanchard.co.uk) with a variety of additional objects, tags, and filters

For my REPL to function properly, the input Liquid needs to be run through the actual Shopify servers, luckily this isn't *too* hard when you combine usage of the [REST Admin API](https://help.shopify.com/api/reference?ref=tomblanchard.co.uk) with [the ability to access alternative theme templates via a view query paramater](https://ecommerce.shopify.com/c/ecommerce-design/t/alternate-index-template-162420/?ref=tomblanchard.co.uk#comment-162427). The mechanism behind this works like this:

- Get Liquid input from the form POST data
- Upload the Liquid input as a new alternate template via the [Asset API](https://help.shopify.com/api/reference/online%5Fstore/asset?ref=tomblanchard.co.uk), e.g. `/templates/index.1nfn38hgj38g.liquid`
- Request the shop with the new alternate tempalte active, e.g. `https://shop-name.myshopify.com/?view=1nfn38hgj38g`
- Return the content
- Delete the alternate template from the theme

My Express route for this looks like:

```javascript
app.post("/", (req, res) => {
  // Get Liquid input from the form POST data
  var input = `{% layout none %}${req.body.input}`;

  // https://github.com/klughammer/node-randomstring
  var template_suffix = randomstring.generate({
    length: 12,
    charset: "alphabetic"
  });

  var asset_key = `templates/index.${template_suffix}.liquid`;

  // Upload the Liquid input as a new alternate template
  shopify.asset.create(shop_theme_id, {
    "key": asset_key,
    "value": input
  })
    .then(() => {
      // Request the shop with the new alternate tempalte active
      return request({
        url: `${shop_url}/?view=${template_suffix}`,
        headers: { "User-Agent": "Mozilla" }
      });
    })
    .then((template_res) => {
      // Delete the alternate template from the theme
      shopify.asset.delete(shop_theme_id, {
        asset: {
          "key": asset_key
        }
      });

      // Return the content
      return res.send(template_res);
    });
});

```

Now on the front-end we just need a form like:

```markup
<form method="post" action="/">
  <textarea name="input"></textarea>
  <button type="submit">Submit</button>
</form>

```

That'll hit the Express route and give us the compiled Liquid output. I wanted a split-screen editor so I do this via AJAX with an input field to the left and the output field to the right.

In the end I opted to develop the entire front-end with [Shopify Polaris](https://polaris.shopify.com/?ref=tomblanchard.co.uk) \- Shopifys own app React powered JS framework. I broke everything down into their own dedicated components, moved all state and methods into a container component `EditorContainer` and used the new [React 16.3.0 Context API](https://medium.com/dailyjs/reacts-%EF%B8%8F-new-context-api-70c9fe01596b?ref=tomblanchard.co.uk) to [avoid prop-drilling](https://itnext.io/compound-components-with-react-v16-3-6679c752bd56?ref=tomblanchard.co.uk).

You can see the source code to the app on [my GitHub](https://github.com/tomblanchard/shopify-liquid-repl?ref=tomblanchard.co.uk).