Quick answer
Load the free, MIT-licensed universal-3d-viewer library with one script tag, then add a <universal-3d-viewer> element with your model’s URL in src. Visitors can rotate, zoom and view the model in AR. Compress the GLB first and add a poster image with lazy loading, so the 3D model does not slow your page down.
On this page
- What are the ways to embed a 3D model?
- How to embed a 3D model with one script tag
- What asset-base-path does
- How to install it from npm
- Which attributes should you use?
- How to keep the page fast
- How to add AR (view in your room)
- How to embed a 3D model in WordPress
- How to embed a 3D model in Shopify
- If the model does not appear
- Frequently asked questions
What are the ways to embed a 3D model?
There are three common approaches. They differ in who hosts the model, which formats work and how much code you write.
- A hosted viewer in an iframe. You upload the model to a 3D platform and paste its embed code. Quick, but the model lives on their servers and the player follows their rules.
- A web component. You add a script tag and an HTML element, and the model stays on your site. Google’s
<model-viewer>works this way for glTF and GLB, as doesuniversal-3d-viewer, which also reads CAD and BIM formats. - A 3D library such as three.js. Full control, but you build the viewer, controls and loading yourself.
| Option | Formats | Model stays on your site | Code needed | Best for |
|---|---|---|---|---|
| Hosted viewer (iframe) | Set by the platform | No | Paste an iframe | Portfolios and quick shares |
| <model-viewer> | glTF and GLB | Yes | One script tag | Product pages with GLB models |
| universal-3d-viewer | GLB, glTF, STL, OBJ, FBX, STEP, IFC and more | Yes | One script tag | Stores, documentation, CAD and BIM content |
| three.js or another 3D library | Any it has a loader for | Yes | You write the viewer | Custom 3D experiences |
The rest of this guide uses universal-3d-viewer, the free, MIT-licensed library behind the MicroPlugins 3D Viewer. Its source is public.
How to embed a 3D model with one script tag
- Get the model ready as a GLB GLB is the web’s standard 3D format. Convert other formats with the 3D Converter, then shrink the file with the 3D Compressor.
- Upload the model file Put the GLB on your own site or a CDN. If it lives on another domain, that server must allow cross-origin requests (CORS).
- Add the script tag Load the viewer library from jsDelivr with one
<script>tag. It registers the<universal-3d-viewer>element. - Place the element Add
<universal-3d-viewer>where the model should appear and setsrcto your model URL.
Here is the whole embed:
<script src="https://cdn.jsdelivr.net/npm/universal-3d-viewer@0.2.0/dist/library/universal-3d-viewer.umd.js"></script>
<universal-3d-viewer
src="/model.glb"
camera-controls
asset-base-path="https://cdn.jsdelivr.net/npm/universal-3d-viewer@0.2.0/public/"
></universal-3d-viewer>
The element is full width and 400 px tall by default. Change its size with CSS, like any block element:
universal-3d-viewer {
height: 500px;
}
The script is the UMD bundle, with three.js inside. Do not load the package’s ES module build with <script type="module">: it imports three by name, which a browser cannot resolve without an import map.
What asset-base-path does
Some models need extra decoder files that are not inside the script: the Draco and Basis decoders, and the WebAssembly engines for CAD and BIM formats. asset-base-path tells the viewer where the draco/, basis/ and wasm/ folders are.
- Plain GLB and glTF need none of these files.
- Draco-compressed GLB, KTX2 textures, STEP and IFC do. Without the right path, the decoders fail to load.
- With the CDN script, point it at the package’s
public/folder on jsDelivr, as in the snippet above. - Self-hosting? Copy those three folders from the package to your server and point
asset-base-pathat them.
Set it before the element starts, since the viewer reads it once.
How to install it from npm
For a site built with Vite, Next.js, Nuxt or another bundler, install the package with three, which it uses as a peer dependency:
npm install universal-3d-viewer three
// Registers the <universal-3d-viewer> element
import 'universal-3d-viewer'
// Or create a viewer from script
import { Universal3DViewer, isAbortError } from 'universal-3d-viewer'
const viewer = new Universal3DViewer({
container: document.getElementById('viewport'),
// Where the draco/, basis/ and wasm/ folders are served from
assetBasePath: '/decoders/',
})
viewer.load('/model.glb').catch((err) => { if (!isAbortError(err)) throw err })
The package is ES modules only. From CommonJS, use await import('universal-3d-viewer'). If you draw your own controls, the universal-3d-viewer/core entry is a smaller build with no element, no built-in UI and no exporters.
See every attribute, event and method
The developer docs cover the web component, the JavaScript API and plugins.
Which attributes should you use?
These are the attributes most embeds need. The developer docs list every other option, from camera limits to hotspots.
| Attribute | What it does | Use it when |
|---|---|---|
poster | Shows an image until the 3D model is ready | Always, for a fast first paint |
loading="lazy" | Starts the 3D engine only when the viewer scrolls into view | The viewer is below the fold |
alt | Labels the model for screen readers | Always |
camera-controls | Lets visitors rotate, pan and zoom | Almost always |
touch-action="pan-y" | Lets vertical swipes scroll the page on phones | The viewer sits in the middle of an article |
ar | Shows an AR button on devices that support AR | Products people want to see in their room |
auto-rotate | Turns the model slowly when nobody is dragging it | Hero displays, not next to text |
up-axis="z" | Stands Z-up models upright | CAD models that load lying on their side |
generate-schema | Adds schema.org 3DModel data for search engines | Pages you want indexed as carrying a 3D model |
<universal-3d-viewer
src="/models/chair.glb"
poster="/models/chair-poster.webp"
alt="Oak dining chair"
loading="lazy"
camera-controls
touch-action="pan-y"
ar
asset-base-path="https://cdn.jsdelivr.net/npm/universal-3d-viewer@0.2.0/public/"
></universal-3d-viewer>
How to keep the page fast
- Compress the GLB first. Textures are often most of a model’s weight. The 3D Compressor shrinks textures and geometry in your browser, and our guide to reducing 3D model file size explains the trade-offs.
- Always set a poster. Visitors see an image at once, and the page’s largest paint does not wait for WebGL.
- Load lazily. With
loading="lazy", nothing 3D starts until the viewer is on screen. Withreveal="manual", it waits until the visitor clicks the poster. - Publish GLB, not CAD files. A STEP or IFC model makes every visitor download a CAD or BIM engine of several megabytes. Convert STEP to GLB or IFC to GLB before you publish.
- Idle costs nothing. The viewer only draws when something changes, and it stops while it is scrolled out of view or the tab is hidden.
How to add AR (view in your room)
Add the ar attribute and the viewer shows an AR button on devices that can use it. On Android it opens the model in the browser with WebXR, or in Google Scene Viewer. On iPhone and iPad it opens Apple’s AR Quick Look.
AR Quick Look needs a USDZ file. You can leave that to the viewer, which builds one from the loaded model, or supply your own with ios-src. The GLB to USDZ converter makes one in your browser.
<universal-3d-viewer
src="/models/lamp.glb"
ios-src="/models/lamp.usdz"
camera-controls
ar
ar-placement="floor"
ar-scale="fixed"
></universal-3d-viewer>
Use ar-placement="wall" for things that hang on a wall. ar-scale="fixed" keeps the model at true size, so a chair cannot be pinched to the size of a sofa.
How to embed a 3D model in WordPress
You do not need a plugin. In the block editor, add a Custom HTML block and paste the snippet, with your own model and poster URLs:
<script src="https://cdn.jsdelivr.net/npm/universal-3d-viewer@0.2.0/dist/library/universal-3d-viewer.umd.js"></script>
<universal-3d-viewer
src="https://example.com/models/drone.glb"
asset-base-path="https://cdn.jsdelivr.net/npm/universal-3d-viewer@0.2.0/public/"
poster="https://example.com/models/drone-thumb.jpg"
camera-controls
auto-rotate
ar
></universal-3d-viewer>
WordPress only keeps script tags for users allowed to post unfiltered HTML, such as administrators. If the viewer disappears when you save, ask an administrator to add the block.
Host the model on your own site if it accepts .glb uploads, or anywhere that serves it over HTTPS with CORS enabled. MicroPlugins WordPress plugins are coming soon.
How to embed a 3D model in Shopify
Shopify stores 3D models as product media, so upload your GLB to the product first. Then add the viewer to your Online Store 2.0 theme:
- In your Shopify admin, go to Online Store, then Themes, then Edit code.
- Under Snippets, add a new snippet named
universal-3d-viewer.liquid. Paste inexamples/shopify/snippet.liquidfrom the source repository. - In your product template, such as
sections/main-product.liquid, render the snippet where the media appears:
{% render 'universal-3d-viewer', product: product %}
The snippet only renders for products that have a 3D model. It uses the product’s preview image as the poster, loads lazily, turns on AR and can recolour the model when a shopper picks a variant.
If the model does not appear
- Blank viewer. Check the
srcURL in a new tab. A model on another domain also needs CORS headers from its server. - Compressed or CAD models fail.
asset-base-pathis missing or wrong, so the decoders cannot load. - The model lies on its side. It was made Z-up. Add
up-axis="z". - The page will not scroll on phones. Add
touch-action="pan-y".
Frequently asked questions
Is universal-3d-viewer free for commercial sites?
Yes. It is released under the MIT licence, so you can use it on commercial sites and online stores. Keep the licence notice that ships with the package when you host the files yourself.
Which 3D formats can I embed?
GLB and glTF are best for the web. The viewer also displays STL, OBJ, FBX, PLY, 3MF, STEP, IGES and IFC, among others. The developer docs have the full format list.
Do I need a server to use it?
No backend is needed. The viewer runs entirely in the visitor’s browser. You only need somewhere to host the model file, such as your own site or a CDN, served over HTTPS.
How big should a 3D model be for the web?
As small as it can be while still looking right. Compress textures and geometry before you publish, and add a poster image so visitors see something at once. The 3D Compressor shows the file size before and after.
Does the embedded viewer support AR on iPhone?
Yes. Add the ar attribute. On iPhone and iPad the viewer opens Apple’s AR Quick Look, and it builds the USDZ file that Quick Look needs from your model, unless you supply your own with ios-src.
How is universal-3d-viewer different from model-viewer?
Both are web components you add with a script tag. model-viewer displays glTF and GLB. universal-3d-viewer also opens CAD, BIM and mesh formats such as STEP, IFC, STL and OBJ, and adds CAD edges, clipping and measurement through its API.
Keep reading
Make your model web-ready
Compress the GLB in your browser, then embed it with one script tag.