GithubHelp home page GithubHelp logo

jerboa88 / gatsby-plugin-component-to-image Goto Github PK

View Code? Open in Web Editor NEW
1.0 1.0 0.0 478 KB

A Gatsby plugin to generate images and PDFs from React components

License: MIT License

JavaScript 0.83% TypeScript 99.17%
gatsby gatsby-plugin gatsbyjs image-generation image-processing open-graph open-graph-generator open-graph-protocol react react-components

gatsby-plugin-component-to-image's Introduction

Project logo

Gatsby Plugin: Component to Image

Project type Language View package on npmjs Repository size Project license

A Gatsby plugin to generate images and PDFs from React components. Useful for dynamically generating Open Graph images, favicons, and more!


About

This plugin was inspired by similar plugins for generating Open Graph images like gatsby-plugin-open-graph-images, gatsby-plugin-satorare, and gatsby-remark-twitter-cards, but is designed to easier to use and more customizable so that it can be used for more than just generating social images.

Features

  • ๐Ÿš€ Works with any React component : Generate images from any valid React component
    • Pass data to the component to customize the content, style, or layout of the generated images per page
    • Not limited by available plugin options like gatsby-remark-twitter-cards
    • Not limited by types of JSX elements or CSS properties supported by the plugin like gatsby-plugin-satorare
  • ๐Ÿ“ท Configurable output filetypes: Generate PNG, JPEG, or WebP images, as well as PDFs
    • Set the quality of the generated images
    • Optimize images for speed or file size
  • ๐Ÿ“‚ Customizable output paths: Full control over paths of the generated pages and images
    • Set the path of the generated pages so that you can exclude them from your sitemap, or reuse them for other purposes
    • Save images to a separate directory
  • ๐ŸŽ›๏ธ Default options: Reuse the same options for multiple images
    • Set default options when adding the plugin to gatsby-config.js
    • Call the setDefaultOptions() function in gatsby-node.js to set them programmatically

Use cases

  • ๐Ÿž๏ธ Social images: Use your existing React components to generate Open Graph images and/or Twitter cards for your blog posts or other content
  • ๐Ÿ–ผ๏ธ Favicons: Dynamically generate favicons for your website
  • ๐Ÿ“„ Documents: Create PDF files for reports, invoices, resumes, or other documents

How it works

  1. When you call the createImage() function from gatsby-node.js, we save the options for that image/PDF and generate a regular Gatsby page from the component you provided.
  2. When the page is built, we use Puppeteer to render the page in a headless browser and, using the options you provided, either:
    1. save a screenshot of the rendered component as an image, or
    2. print the page to a PDF file

Installation

  1. Install the plugin with your favorite package manager:

    npm install jerboa88/gatsby-plugin-component-to-image		# npm
    yarn add jerboa88/gatsby-plugin-component-to-image		# yarn
    pnpm add jerboa88/gatsby-plugin-component-to-image		# pnpm
    bun add github:jerboa88/gatsby-plugin-component-to-image	# bun
  2. Add the plugin to your gatsby-config.js file:

    // gatsby-config.js
    
    module.exports = {
    	plugins: [
    		'gatsby-plugin-component-to-image',
    	],
    }

    You can also set default options for the plugin here:

    // gatsby-config.js
    
    module.exports = {
    	plugins: [
    		{
    			resolve: 'gatsby-plugin-component-to-image',
    			options: {
    				type: 'jpeg',
    				quality: 95,
    			},
    		},
    	],
    }

Usage

This plugin can be used for a variety of purposes, but we will show you how to use it to generate Open Graph images for your blog posts as an example:

  1. Create a component that renders the content you want to appear in the image:

    // src/templates/og-image/blog-post.tsx
    
    import React from 'react';
    import { graphql } from 'gatsby';
    
    const BlogPostOGImage = ({ pageContext }) => {
    	// Props passed to the createImage function with the `context` option
    	const { title, description, postDate } = pageContext;
    	// Props automatically added by `gatsby-plugin-component-to-image`
    	const { size } = pageContext.imageMetadata;
    
    	// Limit the size of the page to the size of the image
    	return (
    		<div style={{
    			maxWidth: size.width,
    			maxHeight: size.height,
    			padding: '1rem',
    			backgroundColor: 'white',
    			textAlign: 'center',
    		}}>
    			<h1>{title}</h1>
    			<p>{description}</p>
    			<p>Published on {postDate}</p>
    		</div>
    	);
    };
    
    export default BlogPostOGImage;

    The pageContext prop is passed to the component by Gatsby when the image is generated. It contains details about the generated image in imageMetadata that you can use to style your component, as well as any other data you passed to the createImage() function via the context prop.

    In this example, we use the size property from imageMetadata to set the maximum width and height of the image, and we use the title, description, and postDate properties from pageContext to customize the content of the image for each blog post.

  2. Call the createImage() function from gatsby-node.js with your desired options:

    // gatsby-node.js
    
    import { resolve, join } from 'path';
    import { createImage } from 'gatsby-plugin-component-to-image';
    
    export const createPages = async ({ actions }) => {
    	// Example blog post details. You could get this data from a CMS or other source
    	const blogPostDetails = {
    		title: 'Blog Post 1',
    		description: 'This is a blog post',
    		postDate: '2022-01-01',
    	};
    
    	// Generate an Open Graph image for the blog post. Pass the blog post details to the page template so that we can use them in the image
    	const imageMetadata = createImage({
    		pagePath: join('/', '__generated', 'open-graph', 'blog-post-1'),
    		imagePath: join('/', 'images', 'open-graph', `blog-post-1.png`),
    		component: resolve('./src/templates/og-image/blog-post.tsx'),
    		size: {
    			width: 1200,
    			height: 630,
    		},
    		context: blogPostDetails,
    	});
    
    	// Create a page for the blog post. Pass the image metadata to the page template so that we can use the image URL in our Open Graph meta tags
    	actions.createPage({
    		path: join('/', 'blog', 'blog-post-1')
    		component: resolve('./src/templates/blog-post.tsx'),
    		context: {
    			...blogPostDetails,
    			imageMetadata: imageMetadata,
    		}
    	});
    };

    The function will return an object with the metadata for the image. If you don't specify certain options, the plugin will use default values which will be returned here.

    For example, the metadata object can be used to:

    • pass the image URL to your page template so that you can use the image in your Open Graph meta tags, or
    • add nodes to the GraphQL schema so that you can query the image metadata in your components
  3. Run gatsby build to generate the image. The image will be saved to the path you specified with the imagePath option

Options

If you want to generate multiple images with the same options, you can set default options that will be reused every time you call createImage().

You can either set default options for the plugin in gatsby-config.js:

// gatsby-config.js

module.exports = {
	plugins: [
		{
			resolve: 'gatsby-plugin-component-to-image',
			options: {
				type: 'webp',
				quality: 100,
				context: {
					siteName: 'My Example Site',
				},
				verbose: true,
			},
		},
	],
}

or call the setDefaultOptions() function in gatsby-node.js:

// gatsby-node.js

import { setDefaultOptions } from 'gatsby-plugin-component-to-image';

setDefaultOptions({
	type: 'webp',
	quality: 100,
	context: {
		siteName: 'My Example Site',
	},
	verbose: true,
});

Most of these options can also be set directly in the createImage() function. Doing this will override any default options you have set previously.

Common Options

These options can either be set via the plugin options in gatsby-config.js, using the setDefaultOptions() function, or passed to the createImage() function.

Note

component is a required option but it has no default value. Make sure to either set in the default options or pass it to the createImage() function.

Option Description Type Default
component A path to the component used to generate the image. required
context Additional context to pass to the image component. You can include any kind of data here that you want to include in your image so that you can access it later from the image component. optional {}
size.width The width of the image in pixels. This value must be between 1 and 16383. optional 1200
size.height The height of the image in pixels. This value must be between 1 and 16383. optional 630
type The file type of the image. This can be one of 'png', 'jpeg', 'webp', or 'pdf'. optional 'png'
quality The quality of the image. The has no effect on PNG images or PDFs. This value must be between 0 and 100. optional undefined
optimizeForSpeed Whether Puppeteer should optimize image encoding for speed instead of file size. This has no effect on PDFs. optional false

Plugin Options

These options must either be set via the plugin options in gatsby-config.js or using the setDefaultOptions() function.

Option Description Type Default
verbose Whether to enable verbose logging. optional false

Job Options

These options must be passed to the createImage() function.

Option Description Type Default
pagePage The destination path where the image component will be generated, relative to the /public directory. You may want to exclude this path from other plugins so that these components are not included in sitemaps, for example. required
imagePath The destination path of the image itself, relative to the /public directory. This should include the file extension of the image. required

Contributing

Contributions, issues, and forks are welcome. See CONTRIBUTING.md for more details.

License

This project is licensed under the MIT License. See LICENSE for details. This project includes various resources which carry their own copyright notices and license terms. See LICENSE-THIRD-PARTY.md for more details.

gatsby-plugin-component-to-image's People

Contributors

jerboa88 avatar

Stargazers

 avatar

Watchers

 avatar

gatsby-plugin-component-to-image's Issues

Fix schema type issue in validator.ts

Argument of type 'BooleanSchema | NumberSchema | StringSchema | ObjectSchema<unknown>' is not assignable to parameter of type 'BooleanSchema & StringSchema & ObjectSchema<unknown> & NumberSchema'.
  Type 'BooleanSchema' is not assignable to type 'BooleanSchema & StringSchema & ObjectSchema<unknown> & NumberSchema'.
    Type 'BooleanSchema' is missing the following properties from type 'StringSchema': alphanum, base64, case, creditCard, and 24 more.ts(2345)

Allow passing options directly to Puppeteer's `Page.screenshot()` function

Remove quality and optimizeForSpeed from the main options object and allow them to be passed to Puppeteer's Page.screenshot(), along with other options, like so:

setDefaultOptions({
  puppeteer: {
    screenshot: {
      quality: 95,
      optimizeForSpeed: true,
      omitBackground: true,
      // ...
    },
    // ...
  },
  // ...
})

Because quality and optimizeForSpeed options are specific to image generation and are not used for any other purpose in the generation code, it makes sense to remove them from the main options object. Allowing arbitrary options to be passed will give user's more flexibility in case they need to customize the behavior of Page.screenshot() for their use case.

Options important for correct behavior of the plugin like path, clip and type should overwrite user-provided options.

Allow passing options directly to Puppeteer's `Page.goto()` function

Remove hardcoded PUPPETEER_WAIT_CONDITION constant and allow options to be passed directly to Puppeteer's Page.goto(), along with other options, like so:

setDefaultOptions({
  puppeteer: {
    goto: {
      timeout: 10000,
      waitUntil: 'networkidle2',
      // ...
    },
    // ...
  },
  // ...
})

Allowing arbitrary options to be passed will give user's more flexibility in case they need to customize the behavior of Page.goto() for their use case.

Allow passing options directly to Puppeteer's `Page.setViewport()` function

Allow options to be passed directly to Puppeteer's Page.setViewport() like so:

setDefaultOptions({
  puppeteer: {
    setViewport: {
      deviceScaleFactor: 1.5,
      isLandscape: true,
      isMobile: true,
      // ...
    },
    // ...
  },
  // ...
})

Allowing arbitrary options to be passed will give user's more flexibility in case they need to customize the behavior of Page.setViewport() for their use case.

Options important for correct behavior of the plugin like width and height should overwrite user-provided options.

Allow passing options directly to Puppeteer's `Page.pdf()` function

Allow options to be passed directly to Puppeteer's Page.pdf() like so:

setDefaultOptions({
  puppeteer: {
    pdf: {
      printBackground: false,
      scale: 1.5, 
      tagged: false,
      // ...
    },
    // ...
  },
  // ...
})

Allowing arbitrary options to be passed will give user's more flexibility in case they need to customize the behavior of Page.pdf() for their use case.

Options important for correct behavior of the plugin like path, width, and height should overwrite user-provided options. printBackground should have a default value of true to ensure similar behavior as Page.screenshot(), but we should allow user's to override this value.

Add verbose flag

A message is printed to the console each time createImage() is called, which may be excessive if there are many images to create. Add a verbose option to toggle printing of these messages

Add option for deleting pages after the the image/PDF is generated

If possible, use the Gatby's deletePage() action to delete pages after the relevant images/PDFs have been generated.

If the user doesn't plan to use the generated pages for any other purpose, removing them can reduce the build size and eliminate the need to manually exclude these pages from other plugins like gatsby-plugin-sitemap.

Consider removing pages by default.

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.