Here's some information upfront: we don't allow you to programmatically replace code in the editors right now. But of course, you can change what goes into the output/preview area, because that's a direct result of your code running.

Let's do this all in JavaScript and utilize a serverless cloud function.

Say this preprocessor is very very simple

All it does is take your HTML, look for all anchor (<a>) links, and adds a special class name to all of them: my-special-class.

We could do this directly in JavaScript on the client side. But let's pretend that we couldn't. For example, the preprocessor does something secret. Or it's so big/complicated it makes sense to let a server handle it.

Get our hands on the HTML

Say we have some HTML in our editor like this:

<div id="process-all-this">
  <p>Lorem, ipsum <a href="#">impedit nam</a> illum officiis</p>
</div>

We can snag all the HTML (and prevent it from grabbing anything else inside the document) like this:

const processingArea = document.querySelector("#process-all-this");
const html = processingArea.innerHTML;

Now we have a variable with all the HTML we want to process.

Set up a Cloud Function to process it.

This will be written in Node.js to run server side. My function here will use the library Cheerio, which is like jQuery in Node. It will accept the HTML, find links, add the class, and return the processed HTML.

const cheerio = require('cheerio@0.19.0')

module.exports = function(context, cb) {
  const $ = cheerio.load(context.body.html);
  $("a").addClass("my-special-class");
  cb(null, { processed_html: $.html() });
};

But where do we run that?

Setting up a Cloud Function

That little bit of code could run any number of places. It's not always the easiest thing in the world to set up, but it ain't that bad. Here's some of the big options...

We'll be using what I find to be the simplest possible tool: Webtask. Webtask is a bit like CodePen in that it has an editor right in the browser. Here's my function set up:

Using the Cloud Function

With that setup, crucially, we get a URL we can hit to get the processed HTML back. JavaScript is ready for this task. We could use any Ajax technique, like jQuery, Axios, or native browser fetch. We'll use fetch here. MDN has a handy little function we'll adapt:

function postData(url, data) {
  return fetch(url, {
    body: JSON.stringify(data),
    cache: 'no-cache',
    headers: {
      'content-type': 'application/json'
    },
    method: 'POST',
    mode: 'cors'
  })
  .then(response => response.json())
}

Then we call that function with our Webtask URL and the HTML we gathered:

postData(
  webtask_url, 
  { html: html } 
)
  .then(data => {
    processingArea.innerHTML = data.processed_html;
  })
  .catch(error => console.error(error))

After a successful call, the innerHTML of the area of HTML we were processing is replaced.

Live Demo

Notice that the links do not have the class my-special-class, but the CSS makes them red. In the output, the links should be red, because the HTML has been processed and replaced.

See the Pen Custom HTML Preprocessor by Chris Coyier (@chriscoyier) on CodePen.

A custom HTML preprocessor indeed!