Introduction

If you don’t know what Open Graph is, it is a powerful set of meta tags that can be included in a website that allows rich data to be displayed on social media platforms and search engines. Learn more about Open Graph.

This project is inspired by Vercel’s similar project.

Steps

  • Install prerequisites
  • Create our Express app
  • Set up our image generation

The tech stack

  • Node.js
    • Express

Installing Prerequisites

First, we need to create an NPM project:

npm init

We need Express and Canvas:

npm i express canvas

Getting Started writing code

In index.js, we need to import the prerequisites we just installed:

const express = require('express');
const { createCanvas } = require('canvas');

const app = express();

And set up our express server:

app.get('/og/:title/:subtitle', (req, res) => {
  const buffer = generateImage({
    title: req.params.title,
    subtitle: req.params.subtitle
  });

  res.writeHead(200, {
    'Content-Type': 'image/png',
    'Content-Length': buffer.length
  });

  res.end(buffer);
})

app.listen(80, () => {
  console.log('App listening on localhost:80');
})

Let’s generate the images

const generateImage = (data) => {
  // Create and configure the canvas:
  const width = 1200;
  const height = 627;
  const canvas = createCanvas(width, height);
  const context = canvas.getContext('2d');

  // Set a black background:
  context.fillStyle = 'black';
  context.fillRect(0, 0, width, height);

  // Set a white border:
  context.strokeStyle = 'white';
  context.lineWidth = 5;
  context.beginPath();
  context.rect(10, 10, width - 20, height - 20)
  context.stroke();

  // Draw the title:
  context.font = `bold 70pt arial`;
  context.fillStyle = 'white';
  context.fillText(data.title, 50, 170);

  // Draw the subtitle:
  context.font = `bold 40pt arial`;
  context.fillStyle = 'white';
  context.fillText(data.subtitle, 50, 170);

  // Render and return our image:
  const buffer = canvas.toBuffer('image/png');

  return buffer;
}

Lets give it a shot!

In your browser, visit localhost/og/title/subtitle and see if you got what you are looking for!

Full Code

const express = require('express');
const { createCanvas } = require('canvas');

const app = express();

const generateImage = (data) => {
  // Create and configure the canvas:
  const width = 1200;
  const height = 627;
  const canvas = createCanvas(width, height);
  const context = canvas.getContext('2d');

  // Set a black background:
  context.fillStyle = 'black';
  context.fillRect(0, 0, width, height);

  // Set a white border:
  context.strokeStyle = 'white';
  context.lineWidth = 5;
  context.beginPath();
  context.rect(10, 10, width - 20, height - 20)
  context.stroke();

  // Draw the title:
  context.font = `bold 70pt arial`;
  context.fillStyle = 'white';
  context.fillText(data.title, 50, 170);

  // Draw the subtitle:
  context.font = `bold 40pt arial`;
  context.fillStyle = 'white';
  context.fillText(data.subtitle, 50, 170);

  // Render and return our image:
  const buffer = canvas.toBuffer('image/png');

  return buffer;
}

app.get('/og/:title/:subtitle', (req, res) => {
  const buffer = generateImage({
    title: req.params.title,
    subtitle: req.params.subtitle
  });

  res.writeHead(200, {
    'Content-Type': 'image/png',
    'Content-Length': buffer.length
  });

  res.end(buffer);
})

app.listen(80, () => {
  console.log('App listening on localhost:80');
})