Build a Web Face

Create a custom web-based visual representation for your objects using HTML/CSS/JS.

What You'll Build

Faces are the visual layer of Dual objects. While image faces are simple, web faces let you create fully interactive displays using HTML, CSS, and JavaScript. In this tutorial you'll build a dynamic loyalty card face that reads object properties in real time.

Step 1, Understand Face Types

Dual supports several face display types:

We'll be creating a WebFace, the most flexible option.

Step 2, Create Your HTML

A web face is a standard HTML page that receives object data through the Dual Bridge API. Here's a minimal loyalty card face:

html
body {
margin: 0; padding: 24px;
font-family: system-ui, sans-serif;
background: linear-gradient(135deg, #0f172a, #1e293b);
color: white; min-height: 100vh;
}
.card { max-width: 360px; margin: 0 auto; }
.points { font-size: 48px; font-weight: bold; color: #15b8a7; }
.tier { text-transform: uppercase; letter-spacing: 2px; opacity: 0.6; }
.name { margin-top: 16px; font-size: 18px; }
DualBridge.onLoad(function(object) {
document.getElementById('tier').textContent = object.properties.tier;
document.getElementById('points').textContent = object.properties.points + ' pts';
document.getElementById('name').textContent = object.properties.holder_name;
});

Step 3, Host Your Face

Upload your HTML file to any static hosting provider (Vercel, Netlify, S3, etc.) and note the public URL. The face URL must be accessible over HTTPS.

Step 4, Register the Face

Attach the web face to your template:

bash
curl -X POST https://api-testnet.dual.network/faces \\
-H "Authorization: Bearer $DUAL_TOKEN" \\
-H "Content-Type: application/json" \\
-d '{
"face": {
"template": "my-org::loyalty-card::v1",
"display_type": "WebFace",
"meta": {
"url": "https://your-cdn.com/loyalty-face.html"
},
"is_default": true
}
}'

Step 5, Test in the Viewer

Retrieve an object minted from this template and view it. The face will load your HTML, inject the object's properties, and render the interactive card.

bash
curl https://api-testnet.dual.network/objects/{objectId} \\
-H "Authorization: Bearer $DUAL_TOKEN" \\
| jq '.properties.faces'

Bridge API Reference: The DualBridge object provides onLoad(), onStateChange(), and performAction() methods for full two-way communication between your face and the Dual platform.

What's Next?

To receive notifications when objects change state, try Set Up Webhooks.