Skip to content
Greg Jopa
GitHubTwitterLinkedIn

Integrating Vexflow with Gatsby.js

— Gatsby.js, Vexflow

My new blog is built with Gatsby.js and my goal is to make easy to insert sheet music and guitar tab into blog posts. I'm a big fan of the Vexflow Music Notation library and for this post I'm going to explain how I got Vexflow working with Gatsby.

Demo

I struggled a bit with server-side rendering, but eventually got it working! Here's the end result:

Loading...

Integration Details

There are 3 things I had to do to get Vexflow working with Gatsby.js.

  1. react-loadable - The Gatsby framework renders everything server-side and Vexflow does not play nicely by default. The Vexflow library depends on 'window' and several other browser features. To work around this issue I used react-loadable to only load my VexflowDemo component on the client-side.
import React from "react";
import Loadable from "react-loadable";
export default Loadable({
// this "./VexflowDemo" component loads Vexflow and draws the sheet music
loader: () => import("./VexflowDemo"),
loading() {
return <div>Loading...</div>;
},
});
  1. DOM Node Ref - the Vexflow library takes care of the complex rendering for creating sheet music. It just needs a specific container element to use. The 'ref' feature makes it easy to share the container element with Vexflow without having to hardcode any id values.

  2. useEffect Hook - the Vexflow rendering process requires a DOM node reference so we need to make sure the DOM is ready. With React, we can accomplish this using 'useEffect' or 'componentDidMount()'.

Here's a snippet showing how to use 'useEffect' with 'ref':

function VexflowDemo(props) {
const notesContainerRef = React.useRef(null);
useEffect(() => {
if (notesContainerRef.current !== null) {
// this draw() function contains all Vexflow code for rendering the sheet music
draw(notesContainerRef.current, props);
}
});
return <div ref={notesContainerRef} />;
}

Check out the full source code for this blog post.