dom-to-svg

repository·main·Indexed 19 days ago

https://github.com/felixfbecker/dom-to-svg

A library for converting HTML DOM nodes into accessible SVG screenshots. It avoids the use of <foreignObject> to ensure compatibility with design tools like Figma and Adobe Illustrator. Features include the ability to inline external resources (fonts and images) as data URIs, support for custom capture areas, and tools for parsing CSS gradients into SVG structures. Designed for browser environments or headless browsers like Puppeteer.

Tokens
2.7K
Snippets
11
Records
14
Agent score
64%

What's inside dom-to-svg

  1. Convert DOM nodes to SVG

    main

    Use dom-to-svg to convert an entire HTML document or a specific DOM element into an accessible SVG representation. This is useful for creating high-quality SVG 'screenshots' that work in design tools like Figma or Illustrator because the library avoids using <foreignObject>.

    import { documentToSVG, elementToSVG } from 'dom-to-svg'
    
    // Capture the whole document
    const svgDocument = documentToSVG(document)
    
    // Capture a specific element
    const svgElement = elementToSVG(document.querySelector('#my-element'))
  2. Understand TraversalContext

    main

    The TraversalContext is an internal object used during the DOM traversal process to maintain state. While typically managed by the library, understanding its properties helps in understanding how the SVG is constructed:

    • svgDocument: The XMLDocument being built.
    • currentSvgParent: The current SVGElement being processed.
    • parentStackingLayer: The current SVGGElement representing the stacking layer.
    • stackingLayers: The collection of all StackingLayers.
    • ancestorMasks: An array of objects containing mask (SVGMaskElement) and forElement (Element), representing overflow: hidden masks from ancestor elements.
    • labels: A Map linking HTMLLabelElement to their string values.
    • getUniqueId: A function to generate unique IDs with a specific prefix.
    • options: The resolved DomToSvgOptions.
  3. Run dom-to-svg in Puppeteer

    main
    The library is designed to run in a browser environment. It is not recommended to use it with JSDOM on the server. If you need to run this in a server-side environment, use a headless browser like Puppeteer to execute the conversion.
  4. Serialize SVG to a string

    main

    The output of documentToSVG or elementToSVG is an SVG DOM document. To obtain the raw SVG string (for saving to a file or passing to other tools), use the standard XMLSerializer API.

    import { documentToSVG } from 'dom-to-svg'
    
    const svgDocument = documentToSVG(document)
    const svgString = new XMLSerializer().serializeToString(svgDocument)
  5. Inline external resources in SVG

    main

    By default, the generated SVG may reference external resources like fonts or images. To make the SVG self-contained and portable, use inlineResources to convert these external assets into data: URIs within the SVG document.

    import { inlineResources } from 'dom-to-svg'
    
    // Inline external resources (fonts, images, etc) as data: URIs
    await inlineResources(svgDocument.documentElement)
  6. Configure DomToSvgOptions

    main

    When using dom-to-svg, you can provide a DomToSvgOptions object to control the output.

    • captureArea: A DOMRectReadOnly that defines the visual area to constrain the SVG to. Elements that do not intersect this area will be excluded from the resulting SVG.
    • keepLinks: A boolean that determines whether <a> tags are included in the SVG to maintain interactivity. Defaults to true.
    const options: DomToSvgOptions = {
      captureArea: { x: 0, y: 0, width: 500, height: 500 },
      keepLinks: true
    };
  7. Parse CSS gradients with parse()

    main

    Use the parse function to convert a CSS gradient string into an array of Gradient nodes. Each node in the returned array represents a parsed gradient structure, including its type, orientation, and color stops.

    import { parse } from 'dom-to-svg'; // Note: Import path depends on your installation
    
    const gradients = parse('linear-gradient(to right, red, blue)');
  8. Convert an entire document to SVG with documentToSVG()

    main

    Use documentToSVG(document, options?) to convert an entire Document into an XMLDocument containing an SVG representation. This is a convenience wrapper around elementToSVG that targets the document.documentElement.

    import { documentToSVG } from 'dom-to-svg';
    
    const svgDocument = documentToSVG(document);
    const svgString = new XMLSerializer().serializeToString(svgDocument);
  9. Convert a DOM element to SVG with elementToSVG()

    main

    Use elementToSVG(element, options?) to convert a specific DOM Element into an XMLDocument containing an SVG representation.

    The function performs the following:

    • Creates a new SVG document with appropriate namespaces (xmlns and xmlns:xlink).
    • Injects a comment indicating the source URL.
    • Attempts to copy and resolve @font-face rules from the element's owner document to ensure fonts are preserved.
    • Traverses the element tree to build the SVG structure.
    • Sets the width, height, and viewBox attributes based on the element's bounding box or the provided captureArea.
    import { elementToSVG } from 'dom-to-svg';
    
    const element = document.querySelector('#my-element');
    const svgDocument = elementToSVG(element);
    
    // To get the SVG string:
    const svgString = new XMLSerializer().serializeToString(svgDocument);
  10. Inline external resources with inlineResources()

    main

    The inlineResources(element) function recursively inlines all external resources within a given DOM element, such as fonts and images. This is useful for ensuring that the resulting SVG is self-contained and does not rely on external network requests for assets.

    Behavior:

    • Fonts: @font-face URLs within <style> elements are replaced with Base64 data: URIs.
    • Binary Images: Images (e.g., PNG, JPEG) are converted into Base64 data: URIs and assigned to the xlink:href attribute.
    • SVG Images: If an <image> element references another SVG, the external SVG is embedded directly into the output SVG structure rather than being treated as a data URI.

    Requirements:

    • The passed element must be attached to a document with a window (defaultView) so that getComputedStyle() can be used correctly.
    • For SVG images to be embedded properly, the <image> element must have an id attribute.
    import { inlineResources } from 'dom-to-svg';
    
    // Assuming 'element' is a DOM node you want to convert
    await inlineResources(element);
  11. Reference ColorStop node types

    main

    A ColorStop represents an individual color within a gradient's colorStops array. It can be one of the following types:

    • LiteralNode: A named color (e.g., value: 'red').
    • HexNode: A hex color without the pound sign (e.g., value: 'ff0000').
    • RgbNode: An RGB color tuple (e.g., value: [255, 0, 0]).
    • RgbaNode: An RGBA color tuple (e.g., value: [255, 0, 0, 1]).
    export type ColorStop = LiteralNode | HexNode | RgbNode | RgbaNode
  12. Reference the Gradient node types

    main

    The parse function returns an array of Gradient objects. A Gradient can be one of the following types:

    • LinearGradientNode: A standard linear gradient.
    • RepeatingLinearGradientNode: A repeating linear gradient.
    • RadialGradientNode: A radial gradient.
    • RepeatingRadialGradientNode: A repeating radial gradient.
    export type Gradient =
    	| LinearGradientNode
    	| RadialGradientNode
    	| RepeatingLinearGradientNode
    	| RepeatingRadialGradientNode