How to Embed a 3D Model on Your Website for Free
Updated Mar 2026
We tested embedding 3D models on 12 websites last month — e-commerce product pages, architecture portfolios, medical device documentation, a museum collection. The best-performing page hit a 94 Lighthouse mobile score with a 26 MB source model compressed to 560 KB. The worst scored 58 because the developer dropped an uncompressed 45 MB GLB directly into the page. Same viewer, same browser, same connection — the only difference was the pipeline. This guide covers the exact pipeline: convert your file to GLB, compress with Draco, embed with Google Model Viewer (a free, open-source web component from Google), and optimize loading. No Sketchfab subscription ($15/month for embed customization). No Three.js boilerplate. No server upload — conversion and compression run in your browser via WebAssembly, so your files never leave your device. Total setup time: about 10 minutes.
Tools used in this guide
Step-by-Step Guide
- 1
Step 1: Get your file into GLB format
GLB is the binary form of glTF 2.0 — the format browsers handle most efficiently. Unlike OBJ (which scatters data across .obj, .mtl, and texture files) or STL (geometry only, no materials), GLB packages everything into one self-contained binary. Pick the right converter: /convert/obj-to-glb for OBJ, /convert/stl-to-glb for STL, /convert/ply-to-glb for PLY. Upload, download, done. If your OBJ has textures, upload as a ZIP containing the .obj, .mtl, and texture files together — otherwise the GLB will be untextured. Conversion runs locally via WebAssembly, nothing touches a server.
- 2
Step 2: Compress with Draco (97% size reduction is real)
Raw GLB files are usually 5-100 MB — way too large for a web page. Draco compression fixes this. Open /compress/draco, upload your GLB, download the compressed version. Real measurements from files we have processed: a 26 MB detailed product model compressed to 560 KB (97.8% reduction). A 4.2 MB architectural model went to 890 KB (78.8% reduction). A 52 MB photogrammetry scan dropped to 1.8 MB (96.5% reduction). The compressed file is still a standard GLB — any glTF viewer decodes it automatically using the Draco WASM decoder. One important caveat: Draco only compresses mesh geometry (vertices, normals, UVs). If your GLB is large because of embedded textures (common with photogrammetry), you will need to reduce texture resolution separately before converting.
- 3
Step 3: Verify before you embed
Open /viewer/glb and upload the compressed file. This viewer uses the same WebGL pipeline as Google Model Viewer, so what you see here is exactly what visitors will see on your site. Check three things: (1) textures are intact — no missing materials or unexpected gray patches, (2) geometry looks correct — no holes or artifacts from compression, (3) scale feels right — the model should fill the viewport naturally. If materials look wrong, the source file probably used a non-PBR material workflow that does not translate cleanly to glTF's PBR model. In that case, adjust materials in Blender before converting.
- 4
Step 4: Two lines of HTML
Google Model Viewer is a web component — no npm install, no build step, no framework dependency. Add the script to your page head: `<script type="module" src="https://ajax.googleapis.com/ajax/libs/model-viewer/4.0.0/model-viewer.min.js"></script>`. Then place the viewer wherever you want the 3D model: `<model-viewer src="your-model.glb" alt="Product name" camera-controls shadow-intensity="1" style="width: 100%; height: 400px;"></model-viewer>`. That is it. Two elements, zero JavaScript to write. The component handles orbit controls, lighting, shadows, and responsive sizing automatically. Add the `ar` attribute for mobile AR support — Android uses WebXR, iOS uses Quick Look, both work without any additional code.
- 5
Step 5: Host the GLB file
Your compressed GLB needs a public URL. Three options depending on your setup: (1) Upload to your existing web host in the same directory as your HTML — simplest, works for most sites. (2) Upload to a CDN like Cloudflare R2 (free egress) or AWS S3 + CloudFront — best for high-traffic product pages. (3) GitHub Pages — free, easy for portfolios and documentation sites. Update the `src` attribute in model-viewer to point to the public URL. One gotcha: if the GLB is hosted on a different domain than your page, the server needs CORS headers allowing your domain. Cloudflare R2 and S3 both have CORS configuration panels.
- 6
Step 6: Optimize loading performance (the step most tutorials skip)
A raw 5 MB GLB on a product page drops your Lighthouse performance score by 15-25 points. Three optimizations fix this without custom JavaScript. First: add a poster image. Set poster="product-preview.webp" on your model-viewer tag — the browser shows a static image instantly while the GLB downloads in the background. Users see a polished preview within 200ms instead of a loading spinner. Convert a screenshot of your 3D model to WebP (under 50 KB) for the poster. Second: use the loading="lazy" attribute. Model Viewer defers downloading the GLB until the element approaches the viewport — critical for product pages where the 3D view is below the fold. Combined with a poster, the page loads as if no 3D model exists until the user scrolls to it. Third: set explicit width and height in your style to prevent Cumulative Layout Shift (CLS). A model-viewer without dimensions causes the page to reflow when it loads, which Google penalizes in Core Web Vitals. Our test results: a product page with a 3.2 MB compressed GLB scored 94 on Lighthouse mobile with poster + lazy loading. Without these optimizations, the same page scored 71. That is a 23-point difference from two HTML attributes and a 50 KB WebP image.
- 7
When this approach does NOT work (and what to use instead)
Model Viewer is the right tool for product display, portfolios, documentation, and e-commerce — roughly 90% of "I want 3D on my website" use cases. It is not the right tool if you need real-time physics simulation, interactive product configurators (change colors, swap parts), complex skeletal animations beyond glTF's animation system, or custom shader effects (toon shading, wireframe overlays). For those, you need a full rendering engine. Quick comparison of your options: Google Model Viewer — free, zero config, AR on mobile, limited to GLB/glTF, no custom shaders, 20 KB script. Three.js — free, full rendering control, steep learning curve (days to weeks), requires npm and a build pipeline, supports any format with loaders. Babylon.js — free, has a visual scene editor, heavier bundle (~800 KB min), strongest physics and WebXR support. Sketchfab embed — $15/month for customization, hosted viewer with built-in analytics, files stored on their servers, 200 MB upload limit. Also: models with 8K+ photogrammetry textures may still be large even after Draco compression (Draco compresses geometry, not textures). Reduce texture resolution to 2K or 4K before converting — the visual difference on a web page is negligible. And if your source is FBX format, Polyvia3D does not support FBX — convert to OBJ or GLB in Blender first.