@arkeytyp/valu-api
Advanced tools
+1
-1
| { | ||
| "name": "@arkeytyp/valu-api", | ||
| "version": "1.1.2", | ||
| "version": "1.1.3", | ||
| "description": "A package for developing iframe applications for Valu Social. Allows invoking functions of registered Valu applications and subscribing to events, as well as other features that enable developers creating own ifram apps for the value social", | ||
@@ -5,0 +5,0 @@ "main": "src/ValuApi.js", |
+143
-55
@@ -230,96 +230,184 @@ The `valu-api` package enables developers to build custom iframe applications for Valu Social. | ||
| The application is embedded inside Valuverse and controlled by the host. | ||
| Valu Social allows third‑party developers to register **mini‑applications** that are rendered inside the platform using **iframes**. | ||
| - Valuverse owns the global routing context | ||
| - Your app receives route updates from Valu | ||
| - Your app should push navigation changes back to Valu | ||
| Each mini‑app: | ||
| * Has a unique **application ID / slug** | ||
| * Is mounted under a dedicated URL namespace in Valu Social | ||
| * Can manage its own internal routing (for example using React Router) | ||
| The host application (Valu Social) and the iframe application must stay **route‑synchronized** to ensure: | ||
| * Correct deep‑linking | ||
| * Proper browser navigation (back / forward) | ||
| * Shareable URLs | ||
| --- | ||
| ## Important Concept: Route Visibility | ||
| ## Application Configuration | ||
| There are **two different routing scopes**: | ||
| A mini‑application is registered with a configuration similar to the following: | ||
| ### Local (App-only) Routing | ||
| Routing handled only inside your application (e.g. React Router). | ||
| ```json | ||
| { | ||
| "id": "demo-app", | ||
| "slug": "demo-app", | ||
| "iframe": { | ||
| "url": "https://sample.texpo.io" | ||
| } | ||
| } | ||
| ``` | ||
| - ✅ App works normally | ||
| - ❌ Routes are **not visible** to Valuverse | ||
| - ❌ No deep linking from the main application | ||
| Key fields: | ||
| ### Valu Routing (Host-aware) | ||
| Routing handled through Valu API. | ||
| * **id / slug** – determines the public URL under valu-social.com | ||
| * **iframe.url** – the base URL loaded inside the iframe | ||
| - ✅ Routes appear in the main application | ||
| - ✅ Deep linking works | ||
| - ✅ Navigation state is shared with Valuverse | ||
| --- | ||
| ## Host → Iframe Route Mapping | ||
| Valu Social automatically maps routes from the host URL to the iframe URL. | ||
| ### Base Route | ||
| When a user opens: | ||
| ``` | ||
| https://valu-social.com/demo-app | ||
| ``` | ||
| Valu Social loads the iframe at: | ||
| ``` | ||
| https://sample.texpo.io/ | ||
| ``` | ||
| --- | ||
| ## Using React Router in an iFrame App | ||
| ### Nested Routes | ||
| Using **React Router inside an iFrame Valu app is totally fine**. | ||
| When a user opens: | ||
| Your application will: | ||
| - render pages correctly | ||
| - navigate normally | ||
| - function as a self-contained UI | ||
| ``` | ||
| https://valu-social.com/demo-app/page/1 | ||
| ``` | ||
| However: | ||
| Valu Social loads the iframe at: | ||
| - those routes are **internal only** | ||
| - they **do not propagate** to Valuverse | ||
| - the main application will not see or control them | ||
| ``` | ||
| https://sample.texpo.io/page/1 | ||
| ``` | ||
| This approach is acceptable for: | ||
| - demo applications | ||
| - prototypes | ||
| - isolated tools | ||
| - apps that do not need host-level routing | ||
| 📌 **Rule:** | ||
| ``` | ||
| /valu-social/<app-slug>/<path> | ||
| → | ||
| <iframe-base-url>/<path> | ||
| ``` | ||
| No additional configuration is required for this behavior. | ||
| --- | ||
| ## Best Practice for Valuverse Applications | ||
| ## Iframe → Host Route Synchronization | ||
| If your application is built to behave like a **native Valuverse app**, the recommended approach is: | ||
| If your mini‑application uses **client‑side routing** (for example React Router), route changes **inside the iframe** are not automatically reflected in the Valu Social URL. | ||
| > **Use Valu routing instead of (or in addition to) local routing.** | ||
| To keep the host URL in sync, your app must explicitly report route changes using: | ||
| ```ts | ||
| valuApi.pushRoute(pathname); | ||
| ``` | ||
| This ensures: | ||
| - consistent navigation behavior | ||
| - correct deep linking | ||
| - visibility in the main application router | ||
| - proper docking and context switching | ||
| * The browser URL updates correctly | ||
| * Deep links work as expected | ||
| * Page refresh restores the correct internal state | ||
| --- | ||
| ## Valu Routing API | ||
| ## React Router Integration (Recommended) | ||
| ### Subscribing to Route Changes | ||
| ### Valu Router Bridge Component | ||
| Valu notifies your application when the route changes: | ||
| Below is a small helper component that listens for route changes and reports them to Valu Social. | ||
| ```ts | ||
| valuApi.addEventListener(ValuApi.ON_ROUTE, (route) => { | ||
| // route example: | ||
| // "/console" | ||
| // "/api/users/id/123" | ||
| }); | ||
| ``` | ||
| import { useEffect } from "react"; | ||
| import { useLocation } from "react-router-dom"; | ||
| import { useValuAPI } from "@/Hooks/useValuApi"; | ||
| ### Pushing a New Route | ||
| export function ValuRouterBridge() { | ||
| const valuApi = useValuAPI(); | ||
| const { pathname } = useLocation(); | ||
| Navigate forward: | ||
| // Iframe → Host | ||
| useEffect(() => { | ||
| if (!valuApi) return; | ||
| valuApi.pushRoute(pathname); | ||
| }, [valuApi, pathname]); | ||
| ```ts | ||
| valuApi.pushRoute("/documentation"); | ||
| return null; | ||
| } | ||
| ``` | ||
| Replacing the Current Route | ||
| Redirect without adding a history entry: | ||
| What this does: | ||
| ```ts | ||
| valuApi.replaceRoute("/console"); | ||
| * Listens to internal route changes via `useLocation()` | ||
| * Pushes the current pathname to Valu Social | ||
| * Keeps host and iframe URLs aligned | ||
| --- | ||
| ## Example Application Setup | ||
| Below is an example of how the bridge is used inside a React application with React Router: | ||
| ```tsx | ||
| export default function Home() { | ||
| return ( | ||
| <BrowserRouter> | ||
| <ValuRouterBridge /> | ||
| <div className="flex flex-col min-h-screen"> | ||
| <TopBar isIFrame={false} /> | ||
| <main className="flex-grow w-full px-4 py-8"> | ||
| <div className="max-w-[1400px] mx-auto"> | ||
| <Routes> | ||
| <Route path="/" element={<Navigate to="/console" replace />} /> | ||
| <Route | ||
| path="/console" | ||
| element={ | ||
| <> | ||
| <Console /> | ||
| <SampleApiCalls /> | ||
| </> | ||
| } | ||
| /> | ||
| <Route path="/storage" element={<ApplicationStorage />} /> | ||
| <Route path="/documentation" element={<Documentation />} /> | ||
| </Routes> | ||
| </div> | ||
| </main> | ||
| <Footer /> | ||
| </div> | ||
| </BrowserRouter> | ||
| ); | ||
| } | ||
| ``` | ||
| --- | ||
| ## Best Practices | ||
| * Always report route changes using `valuApi.pushRoute` | ||
| * Use relative paths (e.g. `/console`, `/page/1`) | ||
| * Ensure your app can handle being opened directly on any route | ||
| ## Sample Project | ||
@@ -326,0 +414,0 @@ |
+2
-2
| import {EventEmitter} from "./EventEmitter.js"; | ||
| import {APIPointer} from "./APIPointer.js"; | ||
| import {guid4, nextId} from "./Utils.js"; | ||
| import {Intent} from "./Intent"; | ||
| import {Intent} from "./Intent.js"; | ||
@@ -314,2 +314,2 @@ export { ValuApplication } from "./ValuApplication.js"; | ||
| } | ||
| } | ||
| } |
42963
4.58%631
0.16%419
26.59%