Skip to main content

Getting started with the React UI

This guide walks you through integrating the ARender viewer into your own application — step by step, from setting up registry access to displaying your first document in the browser.

The ARender viewer is distributed as the arender-ui npm package. It registers an <arender-element> Web Component that integrates into any framework — React, Angular, Vue, Svelte, or plain HTML. The viewer communicates with the ARender rendition backend over REST.

Don't have a project yet? You can create a fresh React application to follow along:

npm create vite@latest my-app -- --template react-ts
cd my-app

Then continue with the steps below.

Prerequisites

  • Access to the ARender npm registry on Cloudsmith (credentials provided by Uxopian)
  • Node.js 20+ and a package manager (npm or yarn)

Step 1 — Configure access to the ARender registry

ARender packages are hosted on a private Cloudsmith registry. Create a .npmrc file at the root of your project with your token:

.npmrc
//npm.cloudsmith.io/uxopian/release/:_authToken=your_token_here

Replace your_token_here with the token provided by Uxopian.

Then add .npmrc to your .gitignore to avoid committing the token:

.gitignore
.npmrc

Step 2 — Install the ARender package

Open a terminal at the root of your project and install the arender-ui package:

npm install arender-ui --registry https://npm.cloudsmith.io/uxopian/release/

Step 3 — Configure the dev server proxy

The viewer needs to reach the rendition backend. In development, your dev server's built-in proxy handles this — no external reverse proxy needed.

note

Uxopian provides a shared demo rendition backend at https://rendition.arender.2026.uxopian.com — available to all, no credentials or installation required. This lets you test the viewer right away. Deploying your own backend is covered in the Installation section.

Add the following proxy configuration to vite.config.ts:

vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
plugins: [react()],
server: {
proxy: {
'/documents': {
target: 'https://rendition.arender.2026.uxopian.com',
changeOrigin: true,
},
'/registry/documents': {
target: 'https://rendition.arender.2026.uxopian.com',
changeOrigin: true,
},
'/annotation': {
target: 'https://rendition.arender.2026.uxopian.com',
changeOrigin: true,
},
},
},
})
tip

To connect to your own backend instead of the demo, change each target to your backend URL (e.g. http://localhost:8761 for Docker Compose). In production, replace the dev proxy with a reverse proxy (Nginx, Ingress) or a BFF. See Docker Compose for deployment guides.

For other frameworks (Next.js, Nuxt, CRA, webpack…), configure your dev server proxy to forward /documents, /registry/documents, and /annotation to the rendition backend. Refer to your framework's documentation.

Step 4 — Embed the viewer

The <arender-element> is a Web Component — a standard HTML element you can drop into any template or JSX just like a <video> or <input>. It encapsulates the entire ARender viewer: no JavaScript instantiation required to display it. You configure it through HTML attributes.

Web Component attributes

The table below lists the attributes you can set directly on the element:

AttributeRequiredDescription
renditionYesURL of the ARender rendition backend. Use / when proxied with Vite, or http://localhost:4200/ with Angular (see Step 3).
urlNoURL of the document to open on startup.
uuidNoID of the document to open on startup (alternative to url).

Set url or uuid directly as HTML attributes to open a document on startup — no JavaScript needed. To load a different document at runtime, use the JavaScript API.

Copy the following into your src/App.tsx file, replacing its entire contents:

src/App.tsx
import { useEffect } from 'react'
import type { ARenderHTMLElement } from 'arender-ui'

// Move these declarations to a global.d.ts in a real project
declare module 'react' {
namespace JSX {
interface IntrinsicElements {
'arender-element': React.HTMLAttributes<HTMLElement> & {
rendition?: string
url?: string
uuid?: string
}
}
}
}
declare global {
interface Window { ARender: ARenderHTMLElement }
}

function App() {
useEffect(() => { import('arender-ui') }, [])

return (
<div style={{ width: '100%', height: '100vh' }}>
<arender-element
rendition="/"
url="https://www.uxopian.com/hubfs/PDFReference15_v5.pdf"
/>
</div>
)
}

export default App
Loading strategy

The examples below use a dynamic import() inside a lifecycle hook (useEffect, onMounted, etc.) rather than a static import at the top of the file. This is intentional for SSR compatibility: arender-ui registers a Web Component using browser APIs (window, document, customElements) that do not exist in Node.js. A static import would crash the build in SSR frameworks like Next.js, Nuxt, or SvelteKit.

If your application is purely client-side (no SSR), a static import at the top of the file works just as well:

import 'arender-ui'

Step 5 — Start the dev server

With the viewer embedded, start your development server and open it in your browser.

If you created a fresh Vite project (as shown in the introduction), run:

npm run dev

Vite will print a local URL — usually http://localhost:5173. Open it in your browser and you should see the ARender viewer loading the sample PDF.

If you use a different package manager, the equivalent command is:

Package managerCommand
yarnyarn dev
pnpmpnpm dev
bunbun dev

For other frameworks, use your usual start command (e.g. npm start for CRA).

tip

If the viewer loads but no document appears, double-check the proxy configuration in Step 3 — the /documents, /registry/documents, and /annotation paths must all be proxied to the rendition backend.

Step 6 — Load a document dynamically

To change the displayed document at runtime, use window.ARender. Calls made before the viewer finishes mounting are queued automatically — no need to wait for any event.

Replace your src/App.tsx with the following complete file:

src/App.tsx
import { useEffect } from 'react'
import type { ARenderHTMLElement } from 'arender-ui'

declare module 'react' {
namespace JSX {
interface IntrinsicElements {
'arender-element': React.HTMLAttributes<HTMLElement> & {
rendition?: string
url?: string
uuid?: string
}
}
}
}
declare global {
interface Window { ARender: ARenderHTMLElement }
}

function App() {
useEffect(() => { import('arender-ui') }, [])

return (
<div style={{ display: 'flex', flexDirection: 'column', height: '100vh' }}>
<div>
<button onClick={() => window.ARender.openDocumentByUrl('https://www.uxopian.com/hubfs/ARender-Mail_viewer_use_case.msg')}>
Change document
</button>
</div>
<arender-element
rendition="/"
url="https://www.uxopian.com/hubfs/PDFReference15_v5.pdf"
style={{ flex: 1 }}
/>
</div>
)
}

export default App

Sample documents

These public URLs can be used for testing (the demo rendition already authorizes https://www.uxopian.com/):

  • PDF: https://www.uxopian.com/hubfs/PDFReference15_v5.pdf
  • Image: https://www.uxopian.com/hubfs/example_image_comparison_unmodified.jpg
  • Email: https://www.uxopian.com/hubfs/ARender-Mail_viewer_use_case.msg

Next steps