API Reference
Technical documentation for the TimberCloud Embeddable Storefront, including the embed script, integration script, URL parameters, and PostMessage API.
Embed Script (embed.js)
The embed script provides the simplest integration method, automatically creating and configuring the iframe.
Usage
<div id="timbercloud-embed"></div>
<script
src="https://embed.timbercloud.com/embed.js"
data-company="your-company-slug"
data-theme="light"
data-width="100%"
data-height="800px"
defer
></script>Attributes
| Attribute | Required | Default | Description |
|---|---|---|---|
data-company | ✅ Yes | — | Your TimberCloud company slug |
data-theme | No | light | Theme: light or dark |
data-width | No | 100% | Width of the embed (CSS value) |
data-height | No | 800px | Height of the embed (CSS value) |
What It Does
The embed.js script automatically:
- Creates the iframe inside the
#timbercloud-embedcontainer - Sets the return URL to the current page (for password reset)
- Handles password reset routing when
timbercloud_routeandcodeparams are present - Listens for URL changes (popstate) for SPA support
- Handles resize messages from the embed
- Cleans URL parameters after password reset completion
How It Works
// The embed.js script performs these operations:
// 1. Reads configuration from script attributes
const companySlug = script.getAttribute('data-company');
const theme = script.getAttribute('data-theme') || 'light';
const width = script.getAttribute('data-width') || '100%';
const height = script.getAttribute('data-height') || '800px';
// 2. Builds the iframe URL with proper parameters
let iframeUrl = `${baseUrl}/${companySlug}`;
// 3. Checks for password reset parameters
const urlParams = new URLSearchParams(window.location.search);
const timbercloudRoute = urlParams.get('timbercloud_route');
const resetCode = urlParams.get('code');
if (timbercloudRoute) {
// Password reset scenario
iframeUrl += `?timbercloud_route=${timbercloudRoute}&code=${resetCode}`;
} else {
// Normal scenario - add return URL
iframeUrl += `?timbercloud_return_url=${encodeURIComponent(currentPageUrl)}`;
}
// 4. Creates and configures the iframe
const iframe = document.createElement('iframe');
iframe.src = iframeUrl;
iframe.style.width = width;
iframe.style.height = height;
// ... additional configuration
// 5. Adds event listeners for URL changes and messagesMessage Handling
The embed script listens for these PostMessage types:
| Message Type | Description |
|---|---|
timbercloud:resize | Resize the iframe to specified height |
timbercloud:clean-url | Remove routing params from URL after password reset |
Integration Script (timbercloud-integration.js)
For iframe-based integrations, the integration script provides similar automatic functionality.
Usage
<iframe
id="timbercloud-embed"
src="https://embed.timbercloud.com/your-company-slug"
width="100%"
height="800"
style="border: none;"
allow="payment"
></iframe>
<script src="https://embed.timbercloud.com/timbercloud-integration.js"></script>What It Does
The integration script automatically:
- Detects TimberCloud iframes on the page
- Appends the return URL to iframe src if not present
- Handles password reset routing from email links
- Sanitizes sensitive parameters from return URLs
- Observes DOM changes for dynamically added iframes
Triggering Re-initialization (SPAs)
For single-page applications, trigger re-initialization after navigation:
window.dispatchEvent(new Event('timbercloud:reinit'));The script also listens to popstate events automatically.
Sensitive Parameter Sanitization
The integration script removes these parameters from return URLs:
codetokenreset_codeauthauth_tokenaccess_tokenrefresh_tokenotpverification_code
URL Parameters
The embed accepts the following URL parameters:
timbercloud_return_url
Specifies the URL to return to after actions like password reset.
<iframe
src="https://embed.timbercloud.com/your-company-slug?timbercloud_return_url=https://yoursite.com/shop"
...
></iframe>Manual usage:
const currentPageUrl = window.location.href;
const embedUrl = `https://embed.timbercloud.com/your-company-slug?timbercloud_return_url=${encodeURIComponent(currentPageUrl)}`;
document.getElementById('timbercloud-embed').src = embedUrl;timbercloud_route
Navigates to a specific internal route within the embed.
<!-- Open directly to login page -->
<iframe
src="https://embed.timbercloud.com/your-company-slug?timbercloud_route=/auth/login"
...
></iframe>Available routes:
| Route | Description |
|---|---|
/ | Product catalog (home) |
/auth/login | Login page |
/auth/register | Registration page |
/auth/forgot-password | Password reset request |
/auth/reset-password | Password reset form (requires code) |
/checkout | Checkout page |
/orders | Order history |
/orders/[id] | Specific order details |
/account | Account settings |
/account/payment-methods | Manage payment methods |
/account/settings | Account settings |
/product/[id] | Product detail page |
code
Used for password reset tokens. Automatically included in password reset email links.
<iframe
src="https://embed.timbercloud.com/your-company-slug?timbercloud_route=/auth/reset-password&code=RESET_TOKEN"
...
></iframe>PostMessage Communication
The embed supports bidirectional communication via the browser's postMessage API.
Messages FROM the Embed
| Message Type | Data | Description |
|---|---|---|
timbercloud-request-url | { type: 'timbercloud-request-url' } | Embed requests current URL |
timbercloud:resize | { type: 'timbercloud:resize', height: number } | Request iframe resize |
timbercloud:clean-url | { type: 'timbercloud:clean-url', action: 'remove-params' } | Clean URL params |
Messages TO the Embed
| Message Type | Data | Description |
|---|---|---|
timbercloud-config | { type: 'timbercloud-config', config: { returnUrl: string } } | Send configuration |
Handling URL Requests (Manual Integration)
window.addEventListener('message', function(event) {
// Security: verify the origin
if (event.origin !== 'https://embed.timbercloud.com') return;
// Check if embed is requesting URL
if (event.data && event.data.type === 'timbercloud-request-url') {
const iframe = document.getElementById('timbercloud-embed');
iframe.contentWindow.postMessage({
type: 'timbercloud-config',
config: {
returnUrl: window.location.href
}
}, 'https://embed.timbercloud.com');
}
});Password Reset Flow
Flow Diagram
┌─────────────────────────────────────────────────────────────────┐
│ 1. User clicks "Forgot Password" in embed │
│ └─> Enters email address │
├─────────────────────────────────────────────────────────────────┤
│ 2. TimberCloud sends password reset email with link: │
│ https://yoursite.com/shop?timbercloud_route=/auth/ │
│ reset-password&code=RESET_TOKEN │
├─────────────────────────────────────────────────────────────────┤
│ 3. User clicks link → Returns to your site │
│ └─> Embed script detects the parameters │
├─────────────────────────────────────────────────────────────────┤
│ 4. Script passes routing params to iframe │
│ └─> Embed navigates to password reset form │
├─────────────────────────────────────────────────────────────────┤
│ 5. User enters new password → Stays on your site │
│ └─> Script cleans URL parameters │
└─────────────────────────────────────────────────────────────────┘Complete Examples
Example 1: Script Embed (Recommended)
<!DOCTYPE html>
<html>
<head>
<title>Shop | Your Site</title>
<link rel="preconnect" href="https://embed.timbercloud.com">
</head>
<body>
<h1>Our Store</h1>
<div id="timbercloud-embed"></div>
<script
src="https://embed.timbercloud.com/embed.js"
data-company="your-company-slug"
data-theme="light"
data-width="100%"
data-height="900px"
defer
></script>
</body>
</html>Example 2: Iframe with Integration Script
<!DOCTYPE html>
<html>
<head>
<title>Shop | Your Site</title>
<link rel="preconnect" href="https://embed.timbercloud.com">
</head>
<body>
<h1>Our Store</h1>
<div style="
position: relative;
left: 50%;
right: 50%;
margin-left: -50vw;
margin-right: -50vw;
width: 100vw;
max-width: 100vw;
overflow: hidden;
padding: 0 16px;
">
<iframe
id="timbercloud-embed"
src="https://embed.timbercloud.com/your-company-slug"
width="100%"
height="1280"
style="border: none; border-radius: 8px; display: block;"
title="Product Catalog"
allow="payment"
></iframe>
</div>
<script src="https://embed.timbercloud.com/timbercloud-integration.js"></script>
</body>
</html>Example 3: Manual Integration (No Scripts)
<!DOCTYPE html>
<html>
<head>
<title>Shop | Your Site</title>
</head>
<body>
<h1>Our Store</h1>
<iframe
id="timbercloud-embed"
width="100%"
height="800"
style="border: none;"
allow="payment"
></iframe>
<script>
const COMPANY_SLUG = 'your-company-slug';
const EMBED_URL = 'https://embed.timbercloud.com';
function initEmbed() {
const iframe = document.getElementById('timbercloud-embed');
const urlParams = new URLSearchParams(window.location.search);
const timbercloudRoute = urlParams.get('timbercloud_route');
const resetCode = urlParams.get('code');
let embedUrl;
if (timbercloudRoute) {
embedUrl = `${EMBED_URL}/${COMPANY_SLUG}?timbercloud_route=${encodeURIComponent(timbercloudRoute)}`;
if (resetCode) {
embedUrl += `&code=${encodeURIComponent(resetCode)}`;
}
} else {
embedUrl = `${EMBED_URL}/${COMPANY_SLUG}?timbercloud_return_url=${encodeURIComponent(window.location.href)}`;
}
iframe.src = embedUrl;
}
window.addEventListener('message', function(event) {
if (event.origin !== 'https://embed.timbercloud.com') return;
if (event.data?.type === 'timbercloud-request-url') {
document.getElementById('timbercloud-embed').contentWindow.postMessage({
type: 'timbercloud-config',
config: { returnUrl: window.location.href }
}, 'https://embed.timbercloud.com');
}
if (event.data?.type === 'timbercloud:clean-url') {
const url = new URL(window.location.href);
url.searchParams.delete('timbercloud_route');
url.searchParams.delete('code');
window.history.replaceState({}, document.title, url.toString());
}
});
document.addEventListener('DOMContentLoaded', initEmbed);
window.addEventListener('popstate', initEmbed);
</script>
</body>
</html>Example 4: React Component
import { useEffect, useRef } from 'react';
export function TimberCloudEmbed({
companySlug,
theme = 'light',
height = '800px'
}) {
const containerRef = useRef(null);
useEffect(() => {
const container = containerRef.current;
if (!container) return;
// Create placeholder div
const embedDiv = document.createElement('div');
embedDiv.id = 'timbercloud-embed';
container.appendChild(embedDiv);
// Load embed script
const script = document.createElement('script');
script.src = 'https://embed.timbercloud.com/embed.js';
script.setAttribute('data-company', companySlug);
script.setAttribute('data-theme', theme);
script.setAttribute('data-width', '100%');
script.setAttribute('data-height', height);
script.defer = true;
container.appendChild(script);
return () => {
container.innerHTML = '';
};
}, [companySlug, theme, height]);
return <div ref={containerRef} />;
}
// Usage
<TimberCloudEmbed
companySlug="your-company-slug"
theme="light"
height="900px"
/>Backend API
The embed communicates with your TimberCloud backend automatically. Key endpoints:
| Endpoint | Purpose |
|---|---|
GET /api/companies?filters[slug]=... | Load company data |
GET /api/products | Fetch products |
GET /api/categories | Fetch categories |
POST /api/orders | Create orders |
POST /api/auth/local | User login |
POST /api/auth/local/register | User registration |
POST /api/auth/forgot-password | Request password reset |
POST /api/auth/reset-password | Complete password reset |
GET /api/customer-orders | Fetch customer's orders |
These API calls are handled internally — you don't need to implement them.
Real-Time Updates
The embed uses Socket.io for real-time data synchronization:
- Order updates: Automatically refreshes when orders change
- Product updates: Real-time product data sync
- Payment updates: Live payment status updates
Socket connection is automatic and requires no configuration.
Security Considerations
Origin Verification
When using PostMessage manually, always verify origins:
window.addEventListener('message', function(event) {
if (event.origin !== 'https://embed.timbercloud.com') return;
// Process message...
});HTTPS Required
All communication occurs over HTTPS. The embed will not function properly on HTTP sites.
Troubleshooting
Embed not loading
- Verify company slug is correct
- For Script Embed: ensure
<div id="timbercloud-embed">comes immediately before the script - Check browser console for errors
- Ensure HTTPS is used
Password reset not working
- Use Script Embed or Iframe + integration script
- Check console for "TimberCloud:" log messages
- Ensure URL parameters aren't stripped by your server
Script Embed: Container not found
- The
<div id="timbercloud-embed">must be the immediate previous sibling of the script - Ensure the div exists before the script runs (use
deferattribute)