One of my [Graphics Dump posts]({{< ref "drawing-simple-cubes" >}}) integrates three.js and KaTeX into the article itself, which was a first for me. I want to use these libraries in future posts, so I want it to be easy and reusable.
**Note:** I had written this setup in 2023, and now [in modern Hugo there is built-in LaTeX support](https://gohugo.io/content-management/mathematics/).
If you aren't familiar, [three.js](https://threejs.org/) is an easy to use WebGL framework/engine and does a lot of useful work out of the box. When you just want to display a mesh, or a primitive and slap some materials on it you can't really get anything better. However, it wasn't very straightforward to integrate it and I also want to use custom GLSL shaders that complicates things a bit.
I self-host my own JavaScript files, and the easiest way to grab a ready-to-use distribution of three.js is from the repository under the "build" directory. To enable three.js for a specific post, I enable it via a parameter in the frontmatter:
That's only half the battle, as we still need to set up the scene and the render loop. To do this, I put the JavaScript files in the page directory. Then using this shortcode I insert a three.js scene inline:
```go
{{ $path := .Get 0 }}
{{ $id := .Get 1 }}
<divclass="threejs-canvas"id="{{ $id }}"></div>
<scripttype="module"src="{{ $path }}"></script>
```
This adds a container and the script itself, and can be used as so:
I add some CSS to the container to take up 50% of the article width, so we need some way to automatically tell three.js to resize as the canvas changes. First, add a ResizeObserver that calls a `resize()` function:
```javascript
const resizeObserver = new ResizeObserver(resize);
[KaTeX](https://katex.org/) is a LaTeX-compatible JavaScript math renderer, and so much easier to integrate than three.js. There's three files we need to include, `katex.js`, `katex.css` and `auto-render.js` (from the `contrib` folder).
The actual code itself is simple, and is just a `<script>` block waiting for the DOM to load. The rest of the snippet is all of the bits of KaTeX you need to actually use it.