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:
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:
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.
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.