npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

next-banner

v1.2.188

Published

Generate Open Graph images for Next.js on build

Downloads

40

Readme

Logo

Next Banner

Generate Open Graph images (og:image) at build using Puppeteer.

What is an Open Graph image?

Open Graph is a protocol for structured metadata for websites. Part of that is a specification for preview images referred to as "og:image". When using that, your website gets a nice preview in social media and messaging apps. For an example, check out ogimage.gallery.

Why this library?

You might just design images in Figma. This is doable, but quickly becomes tedious if you have a lot of pages (like blog posts) or want to change the design. Generating images is much more effective.

Most currently existing solutions run on-demand either in a serverless function or in a service. This is wasteful and could be expensive if demand is high. For example, cold starting Puppeteer to take a screenshot of the page can take 8s per visitor. To counteract this, a CDN can be used, which further increases the amount of things needing setup.

With next-banner, none of that is needed. In true Jamstack fashion, this library generates images at build, using existing infrastructure that you already have.

Features

  • Speed. It uses Puppeteer to render pages, but only on instance, meaning there is only one cold start. On an M1, 100 pages are rendered and captured in 18s.
  • Simple setup. Does not require you to touch Puppeteer, CDNs, or serverless functions.
  • Render using React. Your images are captured pages that you code in React just like you are used to. No SVGs or special template languages.
  • Multiple layouts. You could have one layout for a start page and another for blog posts.
  • Pass any data. Page title and meta description is passed to the layout pages by default, but you can include any data in any structure you want.

Usage

Installation

Use npm or yarn

npm install next-banner
yarn add next-banner

Add this to your scripts in package.json

"postbuild": "next-banner",

Configuration

Edit next.config.js to wrap wrap the config with withNextBanner. The domain property is needed for some social media sites to render the images.

const { withNextBanner } = require("next-banner");

module.exports = withNextBanner({
  nextBanner: {
    domain: "example.com",
  },
  // ... normal Next.js config here.
});

Meta provider

You also need to wrap your _app with <NextBannerMeta> like below. This ads og:image tags to every page and automatically points them to the generated images.

import { NextBannerMeta } from "next-banner";

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <NextBannerMeta>
      <Component {...pageProps} />
    </NextBannerMeta>
  );
}

Layout files

Create a folder called next-banner-layouts/ in your pages/ folder. Then create a file called default.js there and add the following code:

import { Template } from "next-banner";

export default Template;

Custom layouts

To use a custom layout you first need to declare that a page should render another layout using hte setBannerData hook.

pages/post.jsx

import { setBannerData } from "next-banner";

function PostPage() {
  setBannerData({
    layout: "post" // This is the name of the layout file.
  })

  return (
    ...
  )
}

Then you need a layout file. Notice the default (=) parameters in the destructuring. This helps during local development. In production, the hook will return the real data. But locally, data has not been extracted from the pages.

pages/next-banner-layouts/post.jsx

export default function PostLayout() {
  const {
    meta: {
      title = "Placeholder title",
      description = "Placeholder description"
    }
  } = useBannerData();

  return (
    <ScreenshotCanvas>
      <div
        style={{
          display: "flex",
          flexDirection: "row",
          alignItems: "center",
          gap: "20px",
          marginBlockEnd: "30px",
        }}
      >
        <img src="/favicon.ico" alt="" style={{ marginBottom: "70px" }} />

        <div>
          <h1 style={{ fontSize: "5em" }}>{title}</h1>
          <h2 style={{ fontSize: "2em" }}>{description}</h2>
        </div>
    </div>
  </ScreenshotCanvas>
  );
}

Custom data

If you want to add any extra data besides the meta title and description, you can do so with a the setBannerData on the normal (non-layout) page.

import { setBannerData } from "next-banner";

function ImagePage() {
  setBannerData({
    custom: {
      image: "https://example.com/image.jpg"
    }
  })
}

It can then be accessed in layout files using useBannerData.

import { useBannerData } from "next-banner"

function ImageLayout() {
  const {
    custom: {
      image
    }
  } = useBannerData()

  return (
    ... // Your layout here.
  )
}

Example

There is an example showcasing usage here

License

MIT

Contributing

Contributions are always welcome!

See CONTRIBUTING.md for ways to get started.

Feedback

If you have any feedback, please create an issue reach me on twitter.