# How to Use the Three-Assets Feature for Content Reuse Across OfficeCLI Documents

> Master OfficeCLI's three-assets feature for seamless content reuse across documents. Version-lock, auto-resolve modules, and use CDN fallbacks for identical Three.js assets without configuration.

- Repository: [OfficeAI/OfficeCLI](https://github.com/iofficeai/OfficeCLI)
- Tags: how-to-guide
- Published: 2026-08-03

---

**The three-assets feature in OfficeCLI centralizes Three.js resources by version-locking assets in [`ThreeAssets.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/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`](https://github.com/iOfficeAI/OfficeCLI/blob/main/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)](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`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ThreeAssets.cs) generate an **import-map** JSON blob via the `ImportMapJson` property. This map rewrites bare import specifiers to full URLs:

```json
{
  "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/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:

```csharp
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/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:

```csharp
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:

```html
<!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:

```csharp
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 using `CdnEsmThreeUrl` and `CdnEsmGltfLoaderUrl` load from JSDelivr
- The import-map still rewrites bare specifiers, but browsers without import-map support fall back to explicit URLs
- Version `0.170.0` remains 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.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ThreeAssets.cs) locks Three.js to `0.170.0` with mirror and CDN URLs defined in one location.
- **Automatic module resolution**: `ImportMapJson` generates an import-map that rewrites `three` and `three/addons/` imports to versioned URLs.
- **Pipeline integration**: HTML preview builders in [`PowerPointHandler.HtmlPreview.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/PowerPointHandler.HtmlPreview.cs) inject the import-map; shape renderers in [`PowerPointHandler.HtmlPreview.Shapes.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/PowerPointHandler.HtmlPreview.Shapes.cs) use 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`](https://github.com/iOfficeAI/OfficeCLI/blob/main/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.