GithubHelp home page GithubHelp logo

svycal / og-image Goto Github PK

View Code? Open in Web Editor NEW
251.0 2.0 14.0 800 KB

An open graph image generator, by SavvyCal ✨

Home Page: https://og-image.savvycal.com

License: MIT License

Elixir 80.95% Dockerfile 5.25% CSS 0.64% JavaScript 8.25% HTML 3.99% Shell 0.86% Batchfile 0.07%
opengraph-images og-image opengraphprotocol

og-image's Introduction

Open Graph Image Generator by SavvyCal

og-image is a web service for generating Open Graph images for your webpages. This project was originally inspired by Vercel OG image, with some additional features:

✅ Extensible templating system
Tailwind CSS for styling image templates
✅ Emoji support
✅ Ready for deployment to Fly

The result: beautiful open graph images like this one, generated from custom HTML/CSS templates!

OG image example

Source: https://og-image.savvycal.com/image?template=simple_green&text=The+fresh+way+to+find+a+time+to+meet.

Getting started

Fork this repository and clone it locally. You'll need the following prerequisites installed:

Run the bootstrap script to install dependencies:

script/bootstrap

Then, run the following to boot the server:

script/server

Visit http://localhost:4000/image?template=light&text=Hello+World! to see it in action!

Creating your own templates

This projects contains light and dark templates that display a logo and some user-supplied text. These are just a starting point to give you a sense for how it works. Adding new templates and modifying existing ones is easy!

To get started, open the OgImageWeb.ImageController file.

defmodule OgImageWeb.ImageController do
  use OgImageWeb, :controller

  import OgImageWeb.ImageHelpers
  import OgImageWeb.ImageRenderer

  # Match on the `template` param to decide which template to render. The
  # `render_image` function is a special helper that either renders the PNG
  # (when path is `/image`) or renders the HTML (when path is `/preview`).

  def show(conn, %{"template" => "light", "text" => text}) do
    conn
    |> assign(:text, prepare_html(text))
    |> render_image(:light)
  end

  def show(conn, %{"template" => "dark", "text" => text}) do
    conn
    |> assign(:text, prepare_html(text))
    |> render_image(:dark)
  end

  # -- Add more templates here --

  def show(conn, _params) do
    render_image(conn, :fallback)
  end
end

The template markup is defined in the OgImageWeb.ImageHTML module.

defmodule OgImageWeb.ImageHTML do
  use OgImageWeb, :html

  @doc """
  A logo and text on a light background.
  """
  def light(assigns) do
    ~H"""
    <body class="bg-[#F8F2E6] flex flex-col h-screen">
      <div class="shrink-0 pt-24 px-20 text-gray-900">
        <.savvycal_logo />
      </div>
      <div class="grow flex items-center px-20">
        <h1 class="font-extrabold text-gray-900 text-[7rem] leading-[1.2]">
          <%= @text %>
        </h1>
      </div>
    </body>
    """
  end

  # -- truncated for brevity --
end

These templates are wired up for Tailwind CSS by default. You're welcome to define reuable components and helper functions (like we've done with the <.savvycal_logo /> component, which is defined in the OgImageWeb.SharedComponents module).

The image controller serves content over two different routes:

  • /preview for an HTML preview of the image contents
  • /image for the actual rendered image (in PNG format)

Tip

Use the Responsive Mode and set the viewport to 1200 x 630 pixels to see the HTML preview in the same dimensions as the PNG image. This is great for testing and dialing in your designs quickly (without re-rendering the PNG on every change).

Customizing styles

The CSS styles for image templates are defined in the OgImageWeb.Layouts.image_template_styles/1 component. For performance, all definitions (including fonts) are inlined inside a <style> tag and rendered directly on page (so that the headless browser doesn't need to make any network requests when rendering the image).

Deploying to Fly

This application is ready for Fly deployment with a pre-configured Dockerfile and release scripts.

In short, you'll need to install the Fly CLI, sign up (or log in to your existing) Fly account, run the launch command for initial deployment, and the deploy command for subsequent deployments.

$ fly auth login
$ fly launch
$ fly deploy

For a complete guide to deploying Phoenix applications (like this one), check out the guide: https://hexdocs.pm/phoenix/fly.html.

How It (Technically) Works

We're employing a time-honored technique of screenshotting the contents of a headless browser (via Puppeteer) to generate images. Since the rest of the project is implemented in Elixir, we rely on the nodejs hex package to interface with a pool of Node.js processes.

We define two Node.js functions:

  • emojify for converting emoji to images
  • takeScreenshot for rendering templates in a Puppeteer browser and capturing a screenshot

The OgImageWeb.ImageRenderer.render_image/2 function is responsible for dispatching requests the takeScreenshot function and returning the image data via the Plug.Conn.

Observability

New Relic

To enable New Relic monitoring, add your license key to your Fly secrets.

fly secrets set NEW_RELIC_LICENSE_KEY=...

If desired, update NEW_RELIC_APP_NAME in fly.toml to something of your choosing.

Honeybadger

To enable Honeybadger monitoring, add your API key to your Fly secrets.

fly secrets set HONEYBADGER_API_KEY=...

Logflare

To enable Logflare, add your source ID and API key to your Fly secrets.

fly secrets set LOGFLARE_SOURCE_ID=...
fly secrets set LOGFLARE_API_KEY=...

Maintained with ♥️ by the SavvyCal team

og-image's People

Contributors

derrickreimer avatar

Stargazers

Guillermo Galán avatar Kyle McLaren avatar Guilherme Raduenz avatar Daniel Hoelzgen avatar Nasrul Gunawan avatar Raphael Caldas avatar kimihito avatar Gavin Walsh avatar John Chambers avatar Marcos Viana avatar Mokhtar avatar 爱可可-爱生活 avatar rubickecho avatar aladecom avatar Brett McHargue avatar  avatar Jacek Suski avatar Zhu avatar Yos avatar Weldhapi avatar Mike Wilson avatar Daniel Kaiser avatar Taylor Sampson avatar hongxin avatar  avatar Mehmet Aga avatar Maik avatar Jatin Jindal avatar Kainoa Kanter avatar Danilo Leal avatar ted avatar Dale Inverarity avatar Anurag Daksh avatar Vishnu Sharma avatar Eddocode avatar Dorian Karter avatar Alexey Sokolov avatar Nicolas Pulido M. avatar Abdulmumin Yaqeen avatar  avatar Gustavo Manolo avatar  avatar Adrien avatar M. Adilla Ramadhan avatar Brian Howenstein avatar Mahdi Rezaei avatar Adrienne L. Travis avatar Alifio avatar Filip Horvat avatar Edward Brunetiere avatar Geovanny Gil avatar Eleven Estudio avatar  avatar Jeremy Zabala avatar Jian An, Lin avatar Ta Tran avatar Aydin Manzouri avatar Marcus Lane avatar Jun Ng. avatar MR avatar Rajeev R Sharma avatar Seth Messer avatar Alejandro Mesa avatar Mike avatar Rimenes Ribeiro avatar  avatar kyle avatar Raz avatar Waren Gonzaga avatar Onur Ozgur OZKAN avatar Jozhe avatar Takuya Fukuju avatar Wojtek Grojec avatar Kevin avatar Paul Sabou avatar sloane avatar Ivan Lenoble avatar Henricus Louwhoff avatar Jaipal Jadeja avatar Lucas Alves Rego avatar  avatar yupix avatar Jon Insley avatar Kiet Doan avatar Chinmay Shrivastava avatar Andrés Alejos avatar Danh Huynh avatar Amju avatar  avatar Borja Paz Rodríguez avatar Khushi patel avatar  avatar TsutomuN avatar Wahyu Kurniawan avatar  avatar Thin Tran avatar Luc Shelton avatar Marcin Bielak avatar Robi avatar Nathan Gomes avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.