Basic Demo
Interactive introduction to Loggical with all log levels, basic configuration, and object logging. Perfect starting point for new users.
📄 Source Code
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Loggical Basic Usage Demo</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Oxygen, Ubuntu, sans-serif;
line-height: 1.6;
color: #333;
background: #f8f9fa;
padding: 20px;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: white;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.header {
background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
color: white;
padding: 30px;
text-align: center;
}
.header h1 {
font-size: 2.5rem;
margin-bottom: 10px;
}
.header p {
font-size: 1.1rem;
opacity: 0.9;
}
.nav {
background: #e9ecef;
padding: 15px 30px;
border-bottom: 1px solid #dee2e6;
}
.nav a {
color: #495057;
text-decoration: none;
margin-right: 20px;
font-weight: 500;
}
.nav a:hover {
color: #28a745;
}
.content {
padding: 30px;
}
.demo-section {
margin-bottom: 40px;
padding: 25px;
background: #f8f9fa;
border-radius: 8px;
border-left: 4px solid #28a745;
}
.demo-section h2 {
color: #2c3e50;
margin-bottom: 15px;
display: flex;
align-items: center;
gap: 10px;
}
.demo-section .icon {
font-size: 1.5rem;
}
.demo-controls {
display: flex;
gap: 15px;
margin-bottom: 20px;
flex-wrap: wrap;
align-items: center;
}
.demo-button {
background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
color: white;
border: none;
padding: 10px 20px;
border-radius: 6px;
cursor: pointer;
font-weight: 500;
transition: all 0.2s ease;
}
.demo-button:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(40, 167, 69, 0.3);
}
.demo-button.secondary {
background: #6c757d;
}
.demo-button.secondary:hover {
background: #5a6268;
box-shadow: 0 4px 12px rgba(108, 117, 125, 0.3);
}
.demo-button.danger {
background: #dc3545;
}
.demo-button.danger:hover {
background: #c82333;
box-shadow: 0 4px 12px rgba(220, 53, 69, 0.3);
}
.demo-button.warning {
background: #ffc107;
color: #212529;
}
.demo-button.warning:hover {
background: #e0a800;
box-shadow: 0 4px 12px rgba(255, 193, 7, 0.3);
}
.demo-button.info {
background: #17a2b8;
}
.demo-button.info:hover {
background: #138496;
box-shadow: 0 4px 12px rgba(23, 162, 184, 0.3);
}
.demo-button.highlight {
background: #6f42c1;
}
.demo-button.highlight:hover {
background: #5a32a3;
box-shadow: 0 4px 12px rgba(111, 66, 193, 0.3);
}
.demo-button.fatal {
background: #dc3545;
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
box-shadow: 0 0 0 0 rgba(220, 53, 69, 0.7);
}
70% {
box-shadow: 0 0 0 10px rgba(220, 53, 69, 0);
}
100% {
box-shadow: 0 0 0 0 rgba(220, 53, 69, 0);
}
}
.log-output {
background: #1e1e1e;
color: #d4d4d4;
padding: 20px;
border-radius: 8px;
font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas,
monospace;
font-size: 13px;
line-height: 1.4;
overflow-x: auto;
white-space: pre-wrap;
min-height: 100px;
border: 1px solid #333;
margin-top: 15px;
}
.config-panel {
background: white;
border: 1px solid #dee2e6;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
}
.config-row {
display: flex;
gap: 20px;
margin-bottom: 15px;
align-items: center;
flex-wrap: wrap;
}
.config-group {
display: flex;
flex-direction: column;
gap: 5px;
}
.config-group label {
font-weight: 600;
color: #495057;
font-size: 14px;
}
.config-group select,
.config-group input {
padding: 8px 12px;
border: 1px solid #ced4da;
border-radius: 4px;
font-size: 14px;
}
.config-group input[type="checkbox"] {
width: auto;
margin: 0;
}
.checkbox-group {
display: flex;
align-items: center;
gap: 8px;
}
.explanation {
background: #e8f4fd;
border-left: 4px solid #17a2b8;
padding: 15px;
margin: 15px 0;
border-radius: 4px;
}
.explanation h4 {
color: #0c5460;
margin-bottom: 8px;
}
.explanation p {
color: #0c5460;
margin: 0;
}
.code-example {
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 4px;
padding: 15px;
margin: 15px 0;
font-family: "SF Mono", Monaco, "Cascadia Code", monospace;
font-size: 13px;
overflow-x: auto;
}
.clear-button {
background: #6c757d;
color: white;
border: none;
padding: 8px 15px;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
margin-left: auto;
}
.clear-button:hover {
background: #5a6268;
}
/* ANSI color classes */
.ansi-black {
color: #2d3748;
}
.ansi-red {
color: #f56565;
}
.ansi-green {
color: #48bb78;
}
.ansi-yellow {
color: #ed8936;
}
.ansi-blue {
color: #4299e1;
}
.ansi-magenta {
color: #9f7aea;
}
.ansi-cyan {
color: #38b2ac;
}
.ansi-white {
color: #f7fafc;
}
.ansi-gray {
color: #a0aec0;
}
.ansi-bright-red {
color: #fc8181;
}
.ansi-bright-green {
color: #68d391;
}
.ansi-bright-yellow {
color: #f6e05e;
}
.ansi-bright-blue {
color: #63b3ed;
}
.ansi-bright-magenta {
color: #b794f6;
}
.ansi-bright-cyan {
color: #4fd1c7;
}
.ansi-bright-white {
color: #ffffff;
}
.ansi-dim {
opacity: 0.6;
}
.ansi-bold {
font-weight: bold;
}
@media (max-width: 768px) {
.demo-controls {
flex-direction: column;
align-items: stretch;
}
.config-row {
flex-direction: column;
align-items: stretch;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>📚 Basic Usage Demo</h1>
<p>Learn the fundamentals of Loggical with interactive examples</p>
</div>
<div class="nav">
<a href="index.html">← Back to Demos</a>
<a href="playground/">Interactive Playground</a>
<a href="formatting-demo.html">Formatting Showcase</a>
</div>
<div class="content">
<!-- Log Levels Section -->
<div class="demo-section">
<h2><span class="icon">🎯</span>Log Levels</h2>
<div class="explanation">
<h4>Understanding Log Levels</h4>
<p>
Loggical provides 6 log levels with different priorities and
visual styling. Each level serves a specific purpose in your
application logging strategy.
</p>
</div>
<div class="demo-controls">
<button class="demo-button info" onclick="logLevel('debug')">
🐛 DEBUG
</button>
<button class="demo-button" onclick="logLevel('info')">
ℹ️ INFO
</button>
<button class="demo-button warning" onclick="logLevel('warn')">
⚠️ WARN
</button>
<button class="demo-button danger" onclick="logLevel('error')">
❌ ERROR
</button>
<button
class="demo-button highlight"
onclick="logLevel('highlight')"
>
✨ HIGHLIGHT
</button>
<button class="demo-button fatal" onclick="logLevel('fatal')">
💀 FATAL
</button>
<button class="clear-button" onclick="clearOutput('levels-output')">
Clear
</button>
</div>
<div class="code-example">
import { logger } from 'loggical' logger.debug('Detailed diagnostic
information') logger.info('General application flow')
logger.warn('Something needs attention') logger.error('An error
occurred') logger.highlight('Important information')
logger.fatal('Critical system failure')
</div>
<div id="levels-output" class="log-output">
Click the buttons above to see different log levels in action!
</div>
</div>
<!-- Configuration Section -->
<div class="demo-section">
<h2><span class="icon">⚙️</span>Basic Configuration</h2>
<div class="explanation">
<h4>Customizing Your Logger</h4>
<p>
Configure your logger with different options to match your needs.
Try different combinations and see the results immediately.
</p>
</div>
<div class="config-panel">
<div class="config-row">
<div class="config-group">
<label>Color Level</label>
<select id="colorLevel">
<option value="NONE">None</option>
<option value="BASIC">Basic</option>
<option value="ENHANCED" selected>Enhanced</option>
</select>
</div>
<div class="config-group">
<label>Prefix</label>
<input
type="text"
id="prefix"
placeholder="e.g., API, DB, AUTH"
value="DEMO"
/>
</div>
<div class="config-group">
<div class="checkbox-group">
<input type="checkbox" id="timestamps" checked />
<label for="timestamps">Show Timestamps</label>
</div>
</div>
<div class="config-group">
<div class="checkbox-group">
<input type="checkbox" id="symbols" checked />
<label for="symbols">Use Symbols</label>
</div>
</div>
</div>
</div>
<div class="demo-controls">
<button class="demo-button" onclick="testConfiguration()">
🧪 Test Configuration
</button>
<button
class="demo-button secondary"
onclick="resetConfiguration()"
>
🔄 Reset
</button>
<button class="clear-button" onclick="clearOutput('config-output')">
Clear
</button>
</div>
<div class="code-example" id="config-code">
import { Logger, ColorLevel } from 'loggical' const logger = new
Logger({ colorLevel: ColorLevel.ENHANCED, prefix: 'DEMO',
timestamped: true, useSymbols: true })
</div>
<div id="config-output" class="log-output">
Configure the logger above and click "Test Configuration" to see the
results!
</div>
</div>
<!-- Pre-configured Loggers Section -->
<div class="demo-section">
<h2><span class="icon">⚡</span>Pre-configured Loggers</h2>
<div class="explanation">
<h4>Ready-to-Use Logger Instances</h4>
<p>
Loggical provides pre-configured logger instances optimized for
different use cases. These are the recommended way to use Loggical
for most applications.
</p>
<div class="code-example">
<strong>Available Instances:</strong><br />
<code>logger</code> - Standard balanced configuration<br />
<code>compactLogger</code> - Space-efficient with symbols<br />
<code>readableLogger</code> - Enhanced for development<br />
<code>serverLogger</code> - Production-optimized
</div>
</div>
<div class="demo-controls">
<button class="demo-button" onclick="demonstratePreConfigured()">
⚡ Try Pre-configured Loggers
</button>
<button class="demo-button" onclick="compareLoggerTypes()">
🔄 Compare Logger Types
</button>
</div>
<div class="output-container">
<div id="preconfigured-output" class="output"></div>
</div>
</div>
<!-- Object Logging Section -->
<div class="demo-section">
<h2><span class="icon">📦</span>Object & Data Logging</h2>
<div class="explanation">
<h4>Logging Complex Data</h4>
<p>
Loggical handles objects, arrays, errors, and other complex data
types with intelligent formatting and optional compaction.
</p>
</div>
<div class="demo-controls">
<button class="demo-button" onclick="logObject('simple')">
📄 Simple Object
</button>
<button class="demo-button" onclick="logObject('nested')">
🏗️ Nested Object
</button>
<button class="demo-button" onclick="logObject('array')">
📋 Array
</button>
<button class="demo-button danger" onclick="logObject('error')">
💥 Error Object
</button>
<button class="demo-button info" onclick="logObject('mixed')">
🎭 Mixed Data
</button>
<button class="clear-button" onclick="clearOutput('object-output')">
Clear
</button>
</div>
<div class="config-panel">
<div class="config-row">
<div class="config-group">
<div class="checkbox-group">
<input type="checkbox" id="compactObjects" />
<label for="compactObjects">Compact Object Formatting</label>
</div>
</div>
<div class="config-group">
<div class="checkbox-group">
<input type="checkbox" id="redaction" checked />
<label for="redaction"
>Enable Redaction (hides sensitive data)</label
>
</div>
</div>
</div>
</div>
<div class="code-example">
// Objects are automatically formatted logger.info('User data', {
id: 123, name: 'John', email: 'john@example.com' }) // Arrays are
handled intelligently logger.info('Items', ['apple', 'banana',
'cherry']) // Errors include stack traces logger.error('Operation
failed', new Error('Database connection lost'))
</div>
<div id="object-output" class="log-output">
Click the buttons above to see different data types being logged!
</div>
</div>
<!-- Real-world Examples Section -->
<div class="demo-section">
<h2><span class="icon">🌍</span>Real-world Examples</h2>
<div class="explanation">
<h4>Common Logging Patterns</h4>
<p>
See how Loggical works in realistic application scenarios with
proper context and error handling.
</p>
</div>
<div class="demo-controls">
<button class="demo-button" onclick="realWorldExample('api')">
🌐 API Request
</button>
<button class="demo-button" onclick="realWorldExample('database')">
🗄️ Database Operation
</button>
<button class="demo-button" onclick="realWorldExample('auth')">
🔐 Authentication
</button>
<button class="demo-button" onclick="realWorldExample('error')">
🚨 Error Handling
</button>
<button
class="clear-button"
onclick="clearOutput('realworld-output')"
>
Clear
</button>
</div>
<div class="code-example">
// API Request Logging const apiLogger = logger.withPrefix('API')
apiLogger.info('Incoming request', { method: 'POST', endpoint:
'/users', ip: '192.168.1.100' }) apiLogger.info('Request processed',
{ statusCode: 201, duration: '125ms' }) // Database Operations const
dbLogger = logger.withPrefix('DB') dbLogger.info('Query executed', {
table: 'users', operation: 'SELECT', rows: 42 }) // Authentication
Flow const authLogger = logger.withPrefix('AUTH')
authLogger.info('Login attempt', { userId: 'user123', success: true
})
</div>
<div id="realworld-output" class="log-output">
Click the buttons above to see realistic logging scenarios!
</div>
</div>
</div>
</div>
<script type="module">
import {
Logger,
LogLevel,
ColorLevel,
logger,
compactLogger,
readableLogger,
serverLogger,
} from "loggical";
// Global logger instance for demos
let currentLogger = new Logger();
// ANSI to HTML conversion function
function ansiToHtml(text) {
const ansiMap = {
0: "reset",
1: "ansi-bold",
2: "ansi-dim",
30: "ansi-black",
31: "ansi-red",
32: "ansi-green",
33: "ansi-yellow",
34: "ansi-blue",
35: "ansi-magenta",
36: "ansi-cyan",
37: "ansi-white",
90: "ansi-gray",
91: "ansi-bright-red",
92: "ansi-bright-green",
93: "ansi-bright-yellow",
94: "ansi-bright-blue",
95: "ansi-bright-magenta",
96: "ansi-bright-cyan",
97: "ansi-bright-white",
39: "reset-fg",
};
let html = text
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">");
let openSpans = [];
html = html.replace(
/(?:\033\[|\x1b\[|\[)([0-9;]+)m/g,
(match, codes) => {
const codeList = codes.split(";");
let result = "";
codeList.forEach((code) => {
if (code === "0" || code === "39") {
result += "</span>".repeat(openSpans.length);
openSpans = [];
} else if (ansiMap[code]) {
const className = ansiMap[code];
if (className !== "reset" && className !== "reset-fg") {
result += `<span class="${className}">`;
openSpans.push(className);
}
}
});
return result;
}
);
html += "</span>".repeat(openSpans.length);
return html;
}
// Custom transport for capturing output
class DemoTransport {
constructor(outputElementId) {
this.name = "demo";
this.outputElementId = outputElementId;
this.messages = [];
}
write(formattedMessage, metadata) {
this.messages.push(formattedMessage);
const element = document.getElementById(this.outputElementId);
if (element) {
const colorLevel = currentLogger.colorLevel || ColorLevel.ENHANCED;
if (colorLevel === ColorLevel.NONE) {
const plainText = formattedMessage.replace(
/(?:\033\[|\x1b\[|\[)([0-9;]+)m/g,
""
);
element.textContent += plainText + "\n";
} else {
const htmlOutput = ansiToHtml(formattedMessage);
element.innerHTML += htmlOutput + "\n";
}
element.scrollTop = element.scrollHeight;
}
}
}
// Global functions for demo buttons
window.logLevel = function (level) {
const transport = new DemoTransport("levels-output");
const logger = new Logger({ transports: [transport] });
const messages = {
debug: "This is a debug message - detailed diagnostic information",
info: "This is an info message - general application flow",
warn: "This is a warning message - something needs attention",
error:
"This is an error message - an error occurred but app continues",
highlight: "This is a highlight message - important information",
fatal: "This is a fatal message - critical system failure",
};
logger[level](messages[level]);
};
window.testConfiguration = function () {
const colorLevel = document.getElementById("colorLevel").value;
const prefix = document.getElementById("prefix").value;
const timestamps = document.getElementById("timestamps").checked;
const symbols = document.getElementById("symbols").checked;
const transport = new DemoTransport("config-output");
currentLogger = new Logger({
colorLevel: ColorLevel[colorLevel],
prefix: prefix || undefined,
timestamped: timestamps,
useSymbols: symbols,
transports: [transport],
});
// Update code example
const codeExample = document.getElementById("config-code");
codeExample.textContent = `import { Logger, ColorLevel } from 'loggical'
const logger = new Logger({
colorLevel: ColorLevel.${colorLevel},${
prefix ? `\n prefix: '${prefix}',` : ""
}
timestamped: ${timestamps},
useSymbols: ${symbols}
})`;
currentLogger.debug("Debug message with current configuration");
currentLogger.info("Info message with current configuration");
currentLogger.warn("Warning message with current configuration");
currentLogger.error("Error message with current configuration");
};
window.resetConfiguration = function () {
document.getElementById("colorLevel").value = "ENHANCED";
document.getElementById("prefix").value = "DEMO";
document.getElementById("timestamps").checked = true;
document.getElementById("symbols").checked = true;
testConfiguration();
};
window.logObject = function (type) {
const compactObjects =
document.getElementById("compactObjects").checked;
const redaction = document.getElementById("redaction").checked;
const transport = new DemoTransport("object-output");
const logger = new Logger({
compactObjects,
redaction,
transports: [transport],
});
switch (type) {
case "simple":
logger.info("User profile", {
id: 12345,
name: "John Doe",
email: "john.doe@example.com",
active: true,
});
break;
case "nested":
logger.info("Application config", {
database: {
host: "localhost",
port: 5432,
credentials: {
username: "admin",
password: "secret123", // Will be redacted if enabled
},
},
features: {
authentication: true,
logging: { level: "info", format: "json" },
},
});
break;
case "array":
logger.info("Shopping cart items", [
{ id: 1, name: "Laptop", price: 999.99 },
{ id: 2, name: "Mouse", price: 29.99 },
{ id: 3, name: "Keyboard", price: 79.99 },
]);
break;
case "error":
try {
throw new Error("Database connection failed");
} catch (error) {
logger.error("Operation failed", {
error,
context: { operation: "fetchUsers", retryCount: 3 },
});
}
break;
case "mixed":
logger.info("Complex data structure", {
timestamp: new Date(),
user: { id: 123, name: "Alice" },
tags: ["important", "urgent", "customer"],
metadata: null,
count: 42,
enabled: true,
apiKey: "sk_live_abcdef123456", // Will be redacted if enabled
});
break;
}
};
window.realWorldExample = function (scenario) {
const transport = new DemoTransport("realworld-output");
const baseLogger = new Logger({ transports: [transport] });
switch (scenario) {
case "api":
const apiLogger = baseLogger.withPrefix("API");
apiLogger.info("Incoming request", {
method: "POST",
endpoint: "/api/users",
ip: "192.168.1.100",
userAgent: "Mozilla/5.0...",
});
apiLogger.info("Validating request body");
apiLogger.info("Request processed successfully", {
statusCode: 201,
duration: "125ms",
userId: "user_12345",
});
break;
case "database":
const dbLogger = baseLogger.withPrefix("DB");
dbLogger.info("Connecting to database", {
host: "localhost",
database: "app_prod",
});
dbLogger.info("Query executed", {
table: "users",
operation: "SELECT",
rows: 42,
duration: "23ms",
});
dbLogger.warn("Query took longer than expected", {
query: "SELECT * FROM orders WHERE date > ?",
duration: "1.2s",
threshold: "500ms",
});
break;
case "auth":
const authLogger = baseLogger.withPrefix("AUTH");
authLogger.info("Login attempt", {
userId: "user123",
ip: "192.168.1.100",
userAgent: "Chrome/91.0",
});
authLogger.info("Password verification successful");
authLogger.info("JWT token generated", {
userId: "user123",
expiresIn: "24h",
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", // Will be redacted
});
authLogger.info("Login successful", {
userId: "user123",
sessionId: "sess_abc123",
});
break;
case "error":
const errorLogger = baseLogger.withPrefix("ERROR");
try {
// Simulate an error
throw new Error("Payment gateway timeout");
} catch (error) {
errorLogger.error("Payment processing failed", {
error,
orderId: "order_12345",
amount: 99.99,
gateway: "stripe",
retryCount: 3,
context: {
userId: "user123",
timestamp: new Date().toISOString(),
},
});
}
errorLogger.warn("Initiating retry mechanism");
errorLogger.info("Fallback payment method activated");
break;
}
};
window.clearOutput = function (elementId) {
const element = document.getElementById(elementId);
if (element) {
element.innerHTML = "";
element.textContent = "Output cleared. Try the demo buttons above!";
}
};
window.demonstratePreConfigured = function () {
const transport = new DemoTransport("preconfigured-output");
transport.clear();
// Demonstrate each pre-configured logger
const loggers = [
{
name: "logger",
instance: logger,
description: "Standard balanced configuration",
},
{
name: "compactLogger",
instance: compactLogger,
description: "Space-efficient with symbols",
},
{
name: "readableLogger",
instance: readableLogger,
description: "Enhanced for development",
},
{
name: "serverLogger",
instance: serverLogger,
description: "Production-optimized",
},
];
loggers.forEach(({ name, instance, description }) => {
transport.write(`\n=== ${name} (${description}) ===`);
// Create logger with demo transport and same config as the instance
const demoLogger = new Logger({
preset: name === "logger" ? "standard" : name.replace("Logger", ""),
transports: [transport],
});
demoLogger.info("User authentication successful", {
userId: 12345,
method: "oauth",
});
demoLogger.warn("API rate limit approaching", {
current: 85,
limit: 100,
});
demoLogger.error("Database connection failed", {
host: "db.example.com",
timeout: 5000,
});
});
};
window.compareLoggerTypes = function () {
const transport = new DemoTransport("preconfigured-output");
transport.clear();
const message = "Processing user request";
const data = {
requestId: "req_abc123",
userId: 42,
endpoint: "/api/users/profile",
duration: 156.7,
metadata: { userAgent: "Mozilla/5.0", ip: "192.168.1.100" },
};
transport.write("=== Comparing Logger Output Styles ===\n");
// Standard logger
transport.write("📋 Standard Logger:");
const standardLogger = new Logger({ transports: [transport] });
standardLogger.info(message, data);
// Compact logger
transport.write("\n💾 Compact Logger:");
const demoCompactLogger = new Logger({
preset: "compact",
transports: [transport],
});
demoCompactLogger.info(message, data);
// Readable logger
transport.write("\n👁️ Readable Logger:");
const demoReadableLogger = new Logger({
preset: "readable",
transports: [transport],
});
demoReadableLogger.info(message, data);
// Server logger
transport.write("\n🖥️ Server Logger:");
const demoServerLogger = new Logger({
preset: "server",
transports: [transport],
});
demoServerLogger.info(message, data);
};
// Initialize with default configuration
document.addEventListener("DOMContentLoaded", function () {
testConfiguration();
});
</script>
</body>
</html>✨ Features
- ✅ Interactive log level demonstration (DEBUG, INFO, WARN, ERROR, HIGHLIGHT, FATAL)
- ✅ Real-time output display with ANSI color conversion
- ✅ Basic logger configuration options
- ✅ Object and data structure logging examples
- ✅ Browser-based ES module integration
🚀 Running This Demo
bash
# Build the package first
pnpm run build
# Start the demo server
node examples/serve.js
# Then open in your browser:
# http://localhost:3000/basic-demo.html🔗 Related
- ← Back to Examples Overview
- API Reference - Technical documentation
- Getting Started Guide - Setup instructions
This interactive demo is automatically embedded from examples/basic-demo.html.
