How to Use the Three-Assets Feature for Content Reuse Across OfficeCLI Documents
The three-assets feature in OfficeCLI centralizes Three.js resources by version-locking assets in ThreeAssets.cs, generating an import-map for automatic module resolution, and providing CDN fallbacks so all documents reuse identical Three.js content without per-file configuration.
The three-assets feature solves a common problem when generating HTML previews from Office documents: ensuring every 3D visualization uses the exact same Three.js version. According to the iOfficeAI/OfficeCLI source code, this system eliminates version drift by defining a single source of truth for all Three.js resources that gets injected into every generated preview. Whether you're rendering PowerPoint slides with 3D models or building custom document pipelines, understanding how three-assets works lets you create consistent, reusable Three.js content across your entire document ecosystem.
How Three-Assets Centralizes Three.js Resources
At the core of the feature is ThreeAssets.cs, which locks the Three.js version and provides both internal mirror URLs and public CDN fallbacks.
Version-Locked Asset Definitions
The ThreeAssets class in [src/officecli/Core/ThreeAssets.cs](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/ThreeAssets.cs) pins Three.js to a specific version:
| Constant | Value | Purpose |
|---|---|---|
Version |
"0.170.0" |
Guaranteed compatible Three.js version |
MirrorEsmBaseUrl |
https://d.officecli.ai/assets/three-0.170.0 |
Internal mirror for fast, reliable access |
CdnEsmThreeUrl |
https://cdn.jsdelivr.net/npm/three@0.170.0/+esm |
Public CDN fallback for core library |
CdnEsmGltfLoaderUrl |
https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/loaders/GLTFLoader.js/+esm |
Public CDN fallback for GLTF loader |
This centralized definition means changing the version in one place updates every document that uses three-assets.
The Import-Map for Bare Module Specifiers
Lines 30-32 of ThreeAssets.cs generate an import-map JSON blob via the ImportMapJson property. This map rewrites bare import specifiers to full URLs:
{
"imports": {
"three": "https://d.officecli.ai/assets/three-0.170.0/build/three.module.js",
"three/addons/": "https://d.officecli.ai/assets/three-0.170.0/examples/jsm/"
}
}
When inserted into an HTML document's <head>, this import-map allows scripts to use import * as THREE from 'three' and automatically resolve to the mirror URLs.
Injecting Three-Assets Into HTML Previews
The preview pipeline consumes ThreeAssets in two distinct phases: static import-map injection and dynamic runtime loading.
Phase 1: Import-Map Embedding
In [PowerPointHandler.HtmlPreview.cs](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/Pptx/PowerPointHandler.HtmlPreview.cs) at line 126, the HTML builder inserts the import-map:
sb.AppendLine($"<script type=\"importmap\">{Core.ThreeAssets.ImportMapJson}</script>");
This single line ensures that any subsequent module imports in the document resolve through the centralized three-assets configuration.
Phase 2: Dynamic Runtime Imports
For 3D shape rendering, [PowerPointHandler.HtmlPreview.Shapes.cs](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/Pptx/PowerPointHandler.HtmlPreview.Shapes.cs) (lines 2867-2868) performs dynamic imports using the CDN fallback URLs:
THREE = await import($"{Core.ThreeAssets.CdnEsmThreeUrl}");
({ GLTFLoader } = await import($"{Core.ThreeAssets.CdnEsmGltfLoaderUrl}"));
The import-map handles internal module resolution, while the explicit CDN URLs guarantee the core library and loader are available even if the mirror is unreachable.
Reusing Three-Assets Configuration Across Custom Documents
Because three-assets produces static, self-contained configuration, you can reuse the same Three.js setup outside OfficeCLI's built-in preview generation.
Extracting and Reusing the Import-Map
Any HTML file can adopt the three-assets configuration by copying the generated import-map:
<!DOCTYPE html>
<html>
<head>
<!-- Reuse OfficeCLI's three-assets configuration -->
<script type="importmap">
{
"imports": {
"three": "https://d.officecli.ai/assets/three-0.170.0/build/three.module.js",
"three/addons/": "https://d.officecli.ai/assets/three-0.170.0/examples/jsm/"
}
}
</script>
</head>
<body>
<script type="module">
// Resolves to the mirror URL automatically
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// Your Three.js code here...
</script>
</body>
</html>
Programmatic Access in C#
For custom preview builders, access three-assets directly through the OfficeCLI Core:
using OfficeCli.Core;
using System.Text;
// Build custom HTML preview
var sb = new StringBuilder();
// Insert version-locked Three.js import-map
sb.AppendLine($"<!DOCTYPE html><html><head>");
sb.AppendLine($"<script type=\"importmap\">{ThreeAssets.ImportMapJson}</script>");
sb.AppendLine("</head><body>");
// Add your custom content
sb.AppendLine("<div id=\"canvas-container\"></div>");
sb.AppendLine("<script type=\"module\">");
sb.AppendLine(" import * as THREE from 'three';");
sb.AppendLine(" // ...");
sb.AppendLine("</script>");
sb.AppendLine("</body></html>");
File.WriteAllText("custom-preview.html", sb.ToString());
CDN Fallback Behavior and Reliability
The three-assets feature implements a mirror-first, CDN-fallback strategy. When the internal mirror at d.officecli.ai is available, all imports resolve through it for optimal performance. If the mirror fails:
- Dynamic
import()calls usingCdnEsmThreeUrlandCdnEsmGltfLoaderUrlload from JSDelivr - The import-map still rewrites bare specifiers, but browsers without import-map support fall back to explicit URLs
- Version
0.170.0remains consistent regardless of which source serves the files
This dual-path approach ensures Three.js content renders reliably in CI environments, air-gapped networks, and public deployments without configuration changes.
Summary
- Centralized versioning:
ThreeAssets.cslocks Three.js to0.170.0with mirror and CDN URLs defined in one location. - Automatic module resolution:
ImportMapJsongenerates an import-map that rewritesthreeandthree/addons/imports to versioned URLs. - Pipeline integration: HTML preview builders in
PowerPointHandler.HtmlPreview.csinject the import-map; shape renderers inPowerPointHandler.HtmlPreview.Shapes.csuse CDN fallbacks for dynamic imports. - Cross-document reuse: Copy the generated
<script type="importmap">block into any HTML file to inherit the same Three.js configuration without additional setup. - Reliable fallback: Mirror-first loading with automatic CDN fallback ensures consistent rendering across all environments.
Frequently Asked Questions
How do I change the Three.js version used by OfficeCLI?
Edit src/officecli/Core/ThreeAssets.cs and update the Version constant. All mirror URLs, CDN fallbacks, and the import-map automatically reflect the new version. Rebuild OfficeCLI to apply changes across all generated previews.
Can I use three-assets without the internal mirror?
Yes. The CdnEsmThreeUrl and CdnEsmGltfLoaderUrl properties provide public CDN URLs that work independently. Replace ImportMapJson references with explicit JSDelivr URLs if you need to bypass the internal mirror entirely.
Why does OfficeCLI use both import-maps and dynamic imports?
The import-map enables clean bare specifiers (import 'three') in user code, while dynamic imports with explicit CDN URLs ensure the core library and GLTF loader are available for shape rendering even when the import-map fails to load or the browser lacks support.
Is the three-assets configuration compatible with bundlers?
The generated import-map follows the standard Import Maps specification. Webpack, Vite, and Rollup can consume these mappings through plugins, or you can extract the underlying URLs from ThreeAssets.MirrorEsmBaseUrl and ThreeAssets.CdnEsmThreeUrl for direct use in build configurations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →