--- name: joonweb-app-bridge description: Comprehensive guidelines for building embedded apps with Joonweb App Bridge (React, Node, Vanilla JS) --- # Joonweb App Bridge Skill Joonweb apps run embedded inside the Joonweb Admin dashboard via an iframe. Secure iframe communication and session verification are required. ## 1. Core Architecture - **Vanilla JS**: CDN script `https://apps.joonweb.com/app-bridge.js`. - **React App Bridge**: `@joonweb/app-bridge-react`. Provides `` and `useAppBridge()`. - **Node.js App Bridge**: `@joonweb/app-bridge-node`. Provides `requireAppBridgeSession()` middleware for Express. ## 2. React Integration (`@joonweb/app-bridge-react`) Always wrap the root app in ``: ```tsx import React from 'react'; import { JoonwebProvider, useAppBridge, AppBridgeLink } from '@joonweb/app-bridge-react'; import { BrowserRouter, Routes, Route } from 'react-router-dom'; export default function App() { const config = { apiKey: process.env.REACT_APP_JOONWEB_API_KEY!, host: new URLSearchParams(window.location.search).get('host') || '', forceRedirect: true, }; return ( } /> ); } function Dashboard() { const { appBridge, isReady } = useAppBridge(); const handleSave = () => { if (isReady && appBridge) { appBridge.actions.Toast.show({ message: 'Settings saved successfully!' }); } }; return (

Dashboard

{/* Use AppBridgeLink to navigate without iframe hard reloads */} Go to Settings
); } ``` ## 3. Node.js Backend Integration (`@joonweb/app-bridge-node`) Protect all backend API routes using HMAC verification: ```javascript const express = require('express'); const JoonWebNodeBridge = require('@joonweb/app-bridge-node'); const app = express(); const bridge = new JoonWebNodeBridge(process.env.JOONWEB_CLIENT_SECRET); // Verify that request originates from Joonweb iframe app.get('/api/store-data', bridge.requireAppBridgeSession(), (req, res) => { const shop = req.query.shop; res.json({ success: true, shop }); }); ``` ## 4. Mandatory HMAC Verification Rules - Initial iframe page loads pass query parameters: `hmac`, `shop`, `timestamp`, `host`. - Never trust query params on backend routes without verifying `hmac` signature against `JOONWEB_CLIENT_SECRET`.