gatsby-transformer-inline-svg

Inline SVGs from any GraphQL source

Usage no npm install needed!

<script type="module">
  import gatsbyTransformerInlineSvg from 'https://cdn.skypack.dev/gatsby-transformer-inline-svg';
</script>

README

gatsby-transformer-inline-svg

npm npm

Maintainability Contributor Covenant

Read and optimize Contentful graqhQL SVG file nodes to render them inline in your website.

If you want to render static SVG files, use https://www.gatsbyjs.org/packages/gatsby-plugin-react-svg/. This plugin is for everybody using svgs that are in Contentful.

Features

  • Read content of your SVG files from Contentful and provides it for manipulation and rendering in GraphQL
  • Optimizes output via SVGO
  • Provides a compact data URI via mini-svg-data-uri
  • Downloads svg and caches it via createRemoteFileNode

Todo

This is still in development, missing features:

  • Support gatsby-source-filesystem nodes
  • The multi-layered cache and queue still tends to handle files twice. This needs to be simplified and fixed

Installation

npm i gatsby-transformer-inline-svg

Usage

Pass your server connection credentials, the remote cache directory and the directories you want to cache to the plugin options in your gatsby-config.js:

gatsby-config.js:

module.exports = {
  plugins: [
    `gatsby-transformer-inline-svg`
  ]
}

GraphQL Query:

... on ContentfulAsset {
  svg {
    content # SVG content optimized with SVGO
    originalContent # Original SVG content
    dataURI # Optimized SVG as compact dataURI
    absolutePath #
    relativePath #
  }
  file {
    contentType
    url
    fileName
    details {
      image {
        width
        height
      }
    }
  }
  fluid (...) {
    ...
  }
}

Rendering:

import React from 'react'
import propTypes from 'prop-types'
import Img from 'gatsby-image'

// Render inline SVG with fallback non-svg images
export default function Image({ svg, fluid, file, alt }) {
  if (file.contentType === 'image/svg+xml') {
    if (svg && svg.content) {
      // Inlined SVGs
      return <div dangerouslySetInnerHTML={{ __html: svg.content }} />
    }

    // SVGs that can/should not be inlined
    return <img src={file.url} alt={alt} />
  }

  // Non SVG images
  return <Img fluid={fluid} alt={alt} />
}

Image.propTypes = {
  svgContent: propTypes.string,
  fluid: propTypes.object,
  file: propTypes.object.isRequired,
  alt: propTypes.string.isRequired,
}