{"id":15736,"library":"oc-client-browser","title":"OpenComponents Browser Client","description":"The `oc-client-browser` package is the client-side JavaScript library for the OpenComponents (OC) framework, facilitating browser-based rendering of independently deployed micro-frontends. OpenComponents, an open-source framework developed at OpenTable, enables building and managing self-contained UI components (HTML, CSS, JS, often with server-side Node.js logic) that are published to a central OC registry. Currently at version 2.1.10, the client integrates by being included as a script in a web page, exposing a global `oc` object. It automatically scans the DOM for `<oc-component>` custom elements, fetches component data and compiled views from a configured OC registry, and dynamically injects rendered HTML and executes client-side JavaScript. This library is crucial for the OC philosophy, which emphasizes framework-agnosticism, granular UI ownership, and independent deployment to combat monolithic frontend architectures.","status":"active","version":"2.1.10","language":"javascript","source_language":"en","source_url":"https://github.com/opencomponents/oc-client-browser","tags":["javascript","oc","opencomponents","typescript"],"install":[{"cmd":"npm install oc-client-browser","lang":"bash","label":"npm"},{"cmd":"yarn add oc-client-browser","lang":"bash","label":"yarn"},{"cmd":"pnpm add oc-client-browser","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The `oc-client-browser` library is designed for browser global scope access via a script tag. It exposes the `oc` object globally. Direct ES module `import` or CommonJS `require` is not the primary or recommended way to use its runtime.","wrong":"import oc from 'oc-client-browser';\nconst oc = require('oc-client-browser');","symbol":"oc","correct":"<!-- Add <script src=\"https://your-registry.com/oc-client/client.js\"></script> to your HTML -->\n<script>\n  window.oc.cmd.push(function(ocClient) {\n    // Use ocClient object here\n    console.log(ocClient);\n  });\n</script>"},{"note":"To get TypeScript type safety for the global `oc` object, you typically need to declare it globally. If the package also ships types that define the `OCObject` interface, you might import it as a type.","wrong":"import { OCObject } from 'oc-client-browser';","symbol":"OCObject","correct":"declare global {\n  interface Window {\n    oc: OCObject;\n  }\n}\n// Then use `window.oc` in your TypeScript code\n// import type { OCObject } from 'oc-client-browser'; // For types if bundled and exported"},{"note":"Functionality like `build` is accessed directly from the global `oc` object after the script has loaded and initialized.","wrong":"import { build } from 'oc-client-browser'; // Incorrect for runtime usage","symbol":"oc.build","correct":"window.oc.cmd.push(function(ocClient) {\n  const componentHtml = ocClient.build({\n    name: 'my-component',\n    version: '~1.0.0',\n    parameters: { data: 'value' }\n  });\n  document.getElementById('container').innerHTML = componentHtml;\n});"}],"quickstart":{"code":"<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>OC Client Browser Quickstart</title>\n    <style>\n        body { font-family: sans-serif; margin: 20px; }\n        .component-container { border: 1px dashed #ccc; padding: 15px; margin-top: 20px; }\n        oc-component { display: block; min-height: 50px; background-color: #f9f9f9; padding: 10px; }\n    </style>\n</head>\n<body>\n    <h1>OpenComponents Browser Client Example</h1>\n    <p>This page demonstrates client-side rendering of an OpenComponent fetched from a registry.</p>\n\n    <div class=\"component-container\">\n        <h2>Hello World Component</h2>\n        <!-- The oc-component tag tells the client where to render -->\n        <oc-component \n            href=\"https://your-oc-registry.com/components/hello-world/~1.0.0/?name=RegistryUser\"\n            data-oc-params='{\"message\":\"Hello from the browser!\"}'>\n            Loading 'hello-world' component...\n        </oc-component>\n    </div>\n\n    <div class=\"component-container\">\n        <h2>Dynamic Component</h2>\n        <div id=\"dynamic-component-mount\">Loading dynamic component...</div>\n    </div>\n\n    <!-- Optional: Configure global 'oc' settings before loading the client script -->\n    <script>\n        var oc = oc || {};\n        oc.conf = oc.conf || {};\n        oc.conf.retryInterval = 1500; // Retry fetching components every 1.5 seconds on failure\n        oc.conf.baseUrl = 'https://your-oc-registry.com/components'; // Base URL for `oc.build` calls\n    </script>\n\n    <!-- Load the OpenComponents browser client script, ideally at the end of <body> -->\n    <script src=\"https://your-oc-registry.com/oc-client/client.js\"></script>\n\n    <script>\n        // Ensure the global 'oc' object is ready before using it\n        window.oc.cmd.push(function(ocClient) {\n            console.log(\"OpenComponents client is ready! Version:\", ocClient.version);\n\n            // Example of dynamically building and rendering a component\n            const dynamicComponentHtml = ocClient.build({\n                name: 'another-component', // Replace with a valid component name from your registry\n                version: '~1.0.0', // Specify version\n                parameters: { title: 'Generated Component', content: 'This component was built dynamically!' }\n            });\n\n            const mountPoint = document.getElementById('dynamic-component-mount');\n            if (mountPoint) {\n                mountPoint.innerHTML = dynamicComponentHtml;\n                ocClient.renderUnloadedComponents(); // Important: Render dynamically added <oc-component> tags\n            }\n        });\n    </script>\n</body>\n</html>","lang":"typescript","description":"This HTML snippet demonstrates how to include the `oc-client-browser` script, configure global settings, and render OpenComponents using both declarative `<oc-component>` tags and dynamic `oc.build()` calls, ensuring all components are properly initialized and displayed in the browser."},"warnings":[{"fix":"Always include `oc-client-browser` via a `<script>` tag in your HTML. For TypeScript, use global declarations to inform the compiler about the `window.oc` object. If using a bundler for client-side code, ensure it's configured to treat `oc-client-browser` as an external global library.","message":"The `oc-client-browser` library is designed to be included as a global script in HTML. Attempting to `import` or `require` it as an ES module or CommonJS module directly in a Node.js or bundler environment without specific configuration (e.g., polyfills, shims, or a browser field in `package.json`) will likely result in errors or unexpected behavior.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"It is recommended to place the `oc-client-browser` script at the very end of your `<body>` tag. This allows the DOM to be parsed and `<oc-component>` tags to be available before the client initializes and performs its automatic rendering scan. If placing it earlier, ensure you explicitly call `window.oc.renderUnloadedComponents()` after your component tags are present in the DOM.","message":"When including the `oc-client-browser` script in your HTML, the order relative to `<oc-component>` tags matters for automatic rendering. If the script is placed before your component tags, components might not render until `window.oc.renderUnloadedComponents()` is manually called.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure the OC registry URL (specified in `<oc-component href>` or `oc.conf.baseUrl`) is correct and reachable from the client's browser. Monitor browser console for network errors. The client includes a retry mechanism (`oc.conf.retryInterval` and `oc.conf.maxRetries`) which can be configured to tolerate transient issues. Check the OC registry logs for component errors.","message":"Client-side rendering of OpenComponents relies on successful HTTP requests to the configured OC registry. Network issues, registry downtime, or incorrect component `href` attributes can cause components to fail to load, often displaying their fallback content or a loading message indefinitely.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always refer to the official OpenComponents documentation for specific component and registry version compatibility. Pin component versions (`~1.0.0` or `1.2.3`) to prevent unexpected updates. Conduct thorough testing when upgrading any part of the OpenComponents ecosystem to ensure client-side rendering remains stable.","message":"While no specific major version breaking changes for `oc-client-browser` were detailed, the broader OpenComponents ecosystem (including the registry and component definitions) is under active development. Breaking changes in component contracts or registry APIs can indirectly affect the browser client's ability to render components correctly.","severity":"breaking","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Ensure the `<script src=\"...\"></script>` tag for `oc-client-browser` is correctly placed in your HTML, typically at the end of the `<body>`. If you need to interact with `oc` immediately, wrap your code in `window.oc.cmd.push(function(ocClient) { /* ... */ });` to defer execution until the client is ready.","cause":"The `oc-client-browser` script has not been loaded or has not finished initializing before `oc` is accessed.","error":"Uncaught ReferenceError: oc is not defined"},{"fix":"Check the browser's developer console for network errors (e.g., 404, 500 status codes for component requests) or JavaScript errors. Verify the component's `href` URL is correct and the OC registry is online and accessible. If `data-oc-params` is used, ensure the JSON is valid. Check the registry logs for errors related to the component.","cause":"The browser client failed to fetch or render the component from the registry. This can be due to an incorrect component `href`, an unreachable registry, network errors, or an issue with the component itself (e.g., server-side logic error, invalid template).","error":"Component stuck on 'Loading component...' or displaying fallback content indefinitely."},{"fix":"Add a global declaration file (e.g., `src/types/oc-client-browser.d.ts`) to your project. Inside, declare the global `oc` interface and its types. For example: `declare global { interface Window { oc: OCObject; } } interface OCObject { build: (options: any) => string; /* ... other methods */ }`.","cause":"The TypeScript compiler does not know about the global `oc` object that `oc-client-browser` exposes.","error":"TypeScript Error: Property 'oc' does not exist on type 'Window'."}],"ecosystem":"npm"}