Examples System & Browser
The Examples System consists of Three.js's collection of 400+ interactive demos and the web-based browser interface for navigating them. The system includes standardized example authoring patterns, a JSON-based organization structure (files.json and tags.json), and a searchable browser UI with thumbnail previews. The browser loads examples in an iframe, maintains URL-based navigation, and shares UI architecture with the Documentation System (6.3).
For information about the testing infrastructure that validates these examples, see Testing Infrastructure (6.4). For the visual editor that also uses examples, see Visual Editor (6.1).
File Structure and Data Sources
The Examples Browser consists of a static HTML file that dynamically loads example metadata from JSON configuration files.
files.json Structure
The files.json manifest organizes examples into categories. Each category is an object key containing an array of example file names (without .html extension):
{
"webgl": [
"webgl_animation_keyframes",
"webgl_buffergeometry"
],
"webgpu": [
"webgpu_compute_particles"
],
"misc": [
"misc_controls_orbit"
]
}tags.json Structure
The tags.json file maps example names to arrays of search tags and metadata flags:
{
"misc_exporter_gcode": ["community"],
"webgl_clipping": ["solid"],
"webgl_interactive_cubes": ["raycast", "highlight"]
}The "community" tag identifies examples contributed by the community, which receive special visual treatment.
UI Architecture
The Examples Browser uses a panel-viewer layout with card-based navigation, matching the architecture of the Documentation System.
Panel Component
The panel occupies a fixed 300px width on the left side (full width on mobile). It contains:
- Header (examples/index.html15-23): Title and section tabs
- Input Wrapper (examples/index.html29-32): Search field with clear button
- Content Area (examples/index.html34-36): Scrollable list of example cards
- Previews Toggler (examples/index.html35): Icon to toggle between card and minimal view
The panel uses CSS classes to manage states:
.open- Expands panel on mobile.searchFocused- Adjusts UI when search is active.minimal- Hides screenshot previews, shows compact list
Viewer Iframe
The iframe displays the selected example with fullscreen permissions for WebXR:
<iframe id="viewer" name="viewer" allow="fullscreen; xr-spatial-tracking;"></iframe>Position calculation accounts for panel width: padding-left: var(--panel-width) (files/main.css451).
Card Generation
Each example is represented by a card element created by createLink():
The card template includes:
- Screenshot Image: Lazy-loaded, 400px width, 16:9 aspect ratio
- Community Tag: Displayed if example has
"community"in tags array - Formatted Title: Generated by
getName()which removes prefix and converts underscores to slashes
Navigation and Routing
The browser uses hash-based routing to maintain deep links to specific examples.
Link Registration
During navigation build, each example is registered in two data structures:
- links Object (examples/index.html57): Maps filename to DOM element for selection highlighting
- validRedirects Map (examples/index.html58): Maps filename to full path with
.htmlextension for security
The security pattern prevents untrusted URL redirection:
if ( validRedirects.has( file ) === true ) {
selectFile( file );
viewer.src = validRedirects.get( file );
}Click Handling
Card clicks are intercepted to prevent navigation on modified clicks (Ctrl+Click, middle-click):
link.querySelector( 'a[target="viewer"]' ).addEventListener( 'click', function ( event ) {
if ( event.button !== 0 || event.ctrlKey || event.altKey || event.metaKey ) return;
selectFile( file );
} );View Source Button
The floating "View source" button (examples/index.html43) is dynamically configured when an example is selected:
viewSrcButton.style.display = '';
viewSrcButton.href = 'https://github.com/mrdoob/three.js/blob/master/examples/' + selected + '.html';
viewSrcButton.title = 'View source code for ' + getName( selected ) + ' on GitHub';Search and Filtering System
The browser implements client-side search with multi-word support and category-aware filtering.
Multi-Word Search Pattern
The search uses a lookahead pattern to match all words in any order:
function escapeRegExp( string ) {
string = string.replace( /[.*+?^${}()|[]\]/g, '\$&' );
return '(?=.*' + string.split( ' ' ).join( ')(?=.*' ) + ')';
}Example: "webgl animation" becomes (?=.*webgl)(?=.*animation), matching any example containing both words.
Tag Integration
The filterExample() function combines filename with tag array for comprehensive matching:
function filterExample( file, exp, tags ) {
const link = links[ file ];
if ( file in tags ) file += ' ' + tags[ file ].join( ' ' );
const res = file.replace( /_+/g, ' ' ).match( exp );
// ...
}This allows users to search for tags like "raycast", "community", or "ambient occlusion".
URL State Persistence
Search queries are reflected in the URL for shareable links:
if ( v !== '' ) {
window.history.replaceState( {}, '', '?q=' + v + window.location.hash );
} else {
window.history.replaceState( {}, '', window.location.pathname + window.location.hash );
}On page load, the query is extracted and auto-populated:
filterInput.value = extractQuery();
if ( filterInput.value !== '' ) {
panel.classList.add( 'searchFocused' );
updateFilter( files, tags );
}Screenshot System
Each example has a corresponding screenshot used for preview thumbnails.
Screenshot Specifications
| Property | Value |
|---|---|
| Location | examples/screenshots/ |
| Naming | {filename}.jpg (matches example name) |
| Dimensions | 400px width (16:9 aspect ratio) |
| Format | JPEG with compression |
| Loading | Lazy loading via loading="lazy" attribute |
Sources: examples/index.html218
Display Modes
The browser supports two display modes toggled via the previews icon:
Card Mode (default):
- Full screenshot preview with 56.25% padding-bottom (16:9 ratio)
- Screenshot fills container with
position: absolutecentering - Card background color and padding
Minimal Mode (.minimal class):
- Screenshots hidden with
display: none - Text-only list view
- Reduced padding and margins
Screenshot Generation
Screenshots are generated by the testing infrastructure (6.4) using Puppeteer to capture rendered examples. The naming convention ensures automatic correspondence:
webgl_animation_keyframes.html → screenshots/webgl_animation_keyframes.jpgShared Architecture with Documentation System
The Examples Browser and Documentation System (6.3) share significant UI infrastructure to provide a consistent user experience.
Common UI Components
Both systems use identical HTML structure and CSS selectors:
| Component | Selector | Purpose |
|---|---|---|
| Panel Container | #panel | Fixed sidebar with navigation |
| Header | #header | Title and section tabs |
| Search Input | #filterInput | Text filter field |
| Clear Button | #clearSearchButton | Reset search state |
| Content Area | #content | Scrollable navigation |
| Expand Button | #expandButton | Mobile menu toggle |
| Panel Scrim | #panelScrim | Mobile overlay background |
| Viewer Frame | iframe[name="viewer"] | Content display area |
Responsive Behavior
Both systems share the same mobile breakpoint at 640px:
@media all and ( max-width: 640px ) {
#panel {
position: absolute;
width: 100%;
height: var(--header-height);
}
#panel.open {
height: 100%;
}
}On mobile:
- Panel collapses to header-only
- Expand button becomes visible
- Panel slides in from right when opened
- Scrim overlay dims background content
Styling Differences
While sharing layout, the systems have distinct content styling:
Examples Browser:
- Card grid with thumbnails (files/main.css559-604)
- Cover image containers with 16:9 aspect ratio
- Community tag badges
- Previews toggle icon
Documentation System:
- Hierarchical text lists with categories
- Search results with syntax highlighting
- Member function notation (e.g.,
BoxHelper.update()) - Collapsible sections
Example File Organization
Examples follow a strict naming convention that encodes their category and feature focus.
Naming Pattern
{category}_{topic}[_{variant}].htmlExamples:
webgl_animation_keyframes.htmlwebgpu_compute_particles_snow.htmlmisc_controls_orbit.html
Category Prefixes
| Prefix | Count (approx) | Description |
|---|---|---|
| webgl_ | 100+ | WebGL renderer examples |
| webgpu_ | 40+ | WebGPU renderer examples |
| webgl2_ | 5+ | WebGL 2 specific features |
| webxr_ | 10+ | WebXR immersive experiences |
| css2d_, css3d_ | 5+ | CSS rendering techniques |
| misc_ | 20+ | Controls, exporters, utilities |
| physics_ | 10+ | Physics engine integration |
Name Formatting
The getName() function converts filenames to display names:
function getName( file ) {
const name = file.split( '_' );
name.shift(); // Remove category prefix
return name.join( ' / ' );
}Examples:
webgl_animation_keyframes→animation / keyframeswebgpu_compute_particles→compute / particlesmisc_controls_orbit→controls / orbit
Integration with Testing Infrastructure
While the Examples Browser is primarily a navigation tool, it shares infrastructure with the automated testing system described in Testing Infrastructure (6.4):
- Screenshot validation: Thumbnails are generated by the same Puppeteer process that captures regression test images
- Example enumeration: Both use
files.jsonas the source of truth for which examples exist - Naming conventions: Consistent naming enables automatic test generation for each example
- Iframe loading: The testing system uses the same iframe-based loading approach to render examples in isolation
The browser serves as a visual index that developers can use to manually verify example behavior before running automated tests.