Loading DrawUtils
Load BodygramSDKDrawUtils — and its three.js peer dependency — in Vanilla HTML, React, Next.js, and Vue applications.
DrawUtils is shipped as a separate package from the main Headless SDK. You only need to load it on pages where you actually render an avatar.
It also has one peer dependency: three. DrawUtils does not bundle three to keep the download small and to let you reuse the same three instance you may already have on the page.
three version pinning matters for the UMD build. three.js stopped publishing UMD builds after 0.160.0. For the UMD build of DrawUtils you must use three@<=0.160.0. The ES build works with any modern three version — pick whichever you already use.
Script URLs
DrawUtils ships in two build formats. Choose the one that fits your setup.
UMD build
Defines BodygramSDKDrawUtils on window (browser) or globalThis (Node). Load it with a <script> tag — no imports needed. Requires THREE to be defined globally first.
| Channel | URL |
|---|---|
| Prod (stable) | https://headless.body2fit.bodygram.com/sdk.drawutils.umd.js |
ES build
A standard ES module. Import it with <script type="module"> or a bundler. Pulls three in through your importmap or bundler resolution.
| Channel | URL |
|---|---|
| Prod (stable) | https://headless.body2fit.bodygram.com/sdk.drawutils.es.js |
The snippet below is a browser-only example — it relies on the browser's native module loader to fetch the script straight from a URL:
<script type="module">
import BodygramSDKDrawUtils from 'https://headless.body2fit.bodygram.com/sdk.drawutils.es.js';
const utils = new BodygramSDKDrawUtils({ locale: 'en' });
</script>Node.js doesn't support importing from a URL. Importing https://… in a <script type="module"> tag works because browsers fetch ES modules over the network natively, but Node — and most server-side runtimes — only resolve local paths and bare specifiers. If you're consuming DrawUtils in a bundler-driven project (Vite, webpack, Next.js, etc.), install three from npm, download sdk.drawutils.es.js into your project, and import it from a local path so your bundler can inline it at build time — or use the UMD build from a <script> tag. DrawUtils itself is browser-only — it touches document, window, and custom elements — so it should never run in a Node process.
Vanilla HTML
Add three first, then the DrawUtils UMD script. The order matters — DrawUtils reads THREE off the global scope at load time.
<!-- 1. three.js (UMD requires <=0.160.0) -->
<script src="https://unpkg.com/three@0.160.0/build/three.min.js"></script>
<!-- 2. DrawUtils -->
<script src="https://headless.body2fit.bodygram.com/sdk.drawutils.umd.js"></script>BodygramSDKDrawUtils is then available globally:
<script>
const utils = new BodygramSDKDrawUtils({ locale: 'en' });
</script>If you prefer ES modules, use an importmap so DrawUtils can resolve three:
<script type="importmap">
{
"imports": {
"three": "https://esm.sh/three@0.180.0"
}
}
</script>
<script type="module">
import BodygramSDKDrawUtils from 'https://headless.body2fit.bodygram.com/sdk.drawutils.es.js';
const utils = new BodygramSDKDrawUtils({ locale: 'en' });
</script>React
Add three (≤ 0.160.0) and the DrawUtils UMD script to your public/index.html:
<script src="https://unpkg.com/three@0.160.0/build/three.min.js"></script>
<script src="https://headless.body2fit.bodygram.com/sdk.drawutils.umd.js"></script>Once loaded, BodygramSDKDrawUtils is available on window throughout your app:
declare global {
interface Window { BodygramSDKDrawUtils: any; }
}
export function PostureView({ response }: { response: any }) {
useEffect(() => {
const utils = new window.BodygramSDKDrawUtils({ locale: 'en' });
utils.drawFrontPosture(response, { container: 'front-posture' });
utils.drawSidePosture(response, { container: 'side-posture' });
}, [response]);
return (
<>
<div id="front-posture" />
<div id="side-posture" />
</>
);
}If you'd rather install three from npm and use the ES build, add both as dependencies and import them in the component instead:
npm install three'use client';
import { useEffect } from 'react';
export function PostureView({ response }: { response: any }) {
useEffect(() => {
let cancelled = false;
(async () => {
const { default: BodygramSDKDrawUtils } = await import(
/* @vite-ignore */ 'https://headless.body2fit.bodygram.com/sdk.drawutils.es.js'
);
if (cancelled) return;
const utils = new BodygramSDKDrawUtils({ locale: 'en' });
utils.drawFrontPosture(response, { container: 'front-posture' });
utils.drawSidePosture(response, { container: 'side-posture' });
})();
return () => { cancelled = true; };
}, [response]);
return (
<>
<div id="front-posture" />
<div id="side-posture" />
</>
);
}Next.js
Add the scripts to your _document.js or layout.js:
<script src="https://unpkg.com/three@0.160.0/build/three.min.js"></script>
<script src="https://headless.body2fit.bodygram.com/sdk.drawutils.umd.js"></script>Or use the Next.js Script component with strategy="beforeInteractive" so the order is preserved:
import Script from 'next/script';
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<>
<Script
src="https://unpkg.com/three@0.160.0/build/three.min.js"
strategy="beforeInteractive"
/>
<Script
src="https://headless.body2fit.bodygram.com/sdk.drawutils.umd.js"
strategy="beforeInteractive"
/>
{children}
</>
);
}When using DrawUtils in a component, add the 'use client' directive — it's browser-only and reads from window:
'use client';
declare global {
interface Window { BodygramSDKDrawUtils: any; }
}
export function PostureView({ response }: { response: any }) {
useEffect(() => {
const utils = new window.BodygramSDKDrawUtils({ locale: 'en' });
utils.drawFrontPosture(response, { container: 'front-posture' });
utils.drawSidePosture(response, { container: 'side-posture' });
}, [response]);
return (
<>
<div id="front-posture" />
<div id="side-posture" />
</>
);
}Vue
Add the scripts to your public/index.html:
<script src="https://unpkg.com/three@0.160.0/build/three.min.js"></script>
<script src="https://headless.body2fit.bodygram.com/sdk.drawutils.umd.js"></script>Or load them dynamically in your component. Make sure three finishes loading before DrawUtils:
<template>
<div>
<div id="front-posture" />
<div id="side-posture" />
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
const props = defineProps<{ response: any }>();
const ready = ref(false);
function loadScript(src: string) {
return new Promise<void>((resolve, reject) => {
const el = document.createElement('script');
el.src = src;
el.onload = () => resolve();
el.onerror = reject;
document.head.appendChild(el);
});
}
onMounted(async () => {
await loadScript('https://unpkg.com/three@0.160.0/build/three.min.js');
await loadScript('https://headless.body2fit.bodygram.com/sdk.drawutils.umd.js');
const utils = new (window as any).BodygramSDKDrawUtils({ locale: 'en' });
utils.drawFrontPosture(props.response, { container: 'front-posture' });
utils.drawSidePosture(props.response, { container: 'side-posture' });
ready.value = true;
});
</script>Initialization
Once loaded, create one instance and reuse it across draws:
const utils = new BodygramSDKDrawUtils({
locale: 'en', // optional — defaults to 'en'
});For the full constructor option list and accepted locale codes, see Initialization in the API reference (and Supported Locales for the canonical locale table).
