React
A React application displays documents with the Document Viewer component, while an ASP.NET Core backend renders them with TX Text Control .NET Server. Step by step, you build both applications, install the npm package, add the DocumentViewer component, connect it to your backend and load documents with the JavaScript API.
Prerequisites
- Visual Studio 2026 with the .NET 10 SDK for the backend. The engine package requires .NET 8 or higher.
- A TX Text Control .NET Server license and access to the Text Control private NuGet feed.
- Node.js and npm.
- Visual Studio Code or another editor for the React application.
How the Applications Work Together
The React component only contains the viewer's user interface. The documents are loaded and rendered by an ASP.NET Core backend that references the TXTextControl.Web.DocumentViewer package. The component's basePath property contains the URL of this backend. Because the React development server and the backend run on different origins, the backend must allow cross-origin requests (CORS).
Create the Backend
The backend is an ASP.NET Core Web API project with the packages TXTextControl.Web.DocumentViewer and TXTextControl.TextControl.Core.SDK, whose Program.cs adds the Document Viewer middleware and a CORS policy that lets the React application call it. Create it, configure it and start it as described in Create the Backend in the Angular tutorial, and note the HTTPS URL of the backend in Properties/launchSettings.json, for example https://localhost:7275. Leave the backend running while you work on the React application.
Create the React Application
Open a command prompt and create a new React application with Vite. Select React as the framework and JavaScript as the language:
npm create vite@latest my-tx-document-viewer-appChange to the new folder:
cd my-tx-document-viewer-appThe Document Viewer package declares
reactandreact-domversion^18.2.0as peer dependencies, while a new Vite project uses React 19. Install React 18 first, so that the versions match and npm can install the package:npm install react@18 react-dom@18Install the Document Viewer package and open the folder in Visual Studio Code:
npm install @txtextcontrol/tx-react-document-viewer code .
Add the Document Viewer
Open src/App.jsx and replace its content with the following code. Replace https://localhost:7275 with the URL of your backend.
import DocumentViewerPackage from '@txtextcontrol/tx-react-document-viewer';
const DocumentViewer = DocumentViewerPackage.default ?? DocumentViewerPackage;
function App() {
return (
<DocumentViewer
width="1000px"
height="800px"
basePath="https://localhost:7275"
documentData="SGVsbG8gdGhlcmU=">
</DocumentViewer>
);
}
export default App;
documentData contains the text "Hello there" as a Base64-encoded string.
The package is a CommonJS module, and since Vite 8 its default import returns the module object instead of the component, so the code takes the component from the default property; with ??, it also works with earlier Vite versions. Import the Components in Vite 8 explains the change and the error a plain default import causes.
Component Properties
The properties width, height and basePath are required. Others set the document, the docking, the toolbar, text selection, the thumbnail pane, the signature settings and the displayed strings. Pass booleans and objects in curly braces, for example isSelectionActivated={true} or signatureSettings={{ defaultSignatureFont: { family: "Pacifico" } }}. DocumentViewer in the React API reference lists all properties with their types and defaults.
Run the Applications
Make sure that the backend is running in Visual Studio.
In the command prompt, start the React application from the my-tx-document-viewer-app folder:
npm run devOpen
http://localhost:5173in your browser. The Document Viewer shows the text "Hello there". If the viewer doesn't load, check that the backend is running and thatbasePathmatches its URL.

The small gray line above the text is the trial text of the trial packages the screenshot was taken with; see Trial and Licensed Packages.
Load Documents With JavaScript
In many applications, the document is loaded at run time, for example after the user selects it or after it has been downloaded from a Web API. The React component supports the same JavaScript API as all other Document Viewer frontends: the TXDocumentViewer object. Its loadDocument method loads a Base64-encoded document in any supported format.
Load a Document When the Viewer Is Ready
The TXDocumentViewer object doesn't exist immediately when the page is loaded. The viewer raises the documentViewerLoaded event when it is ready to load documents. Use the Effect Hook to register a handler for this event. Replace the content of src/App.jsx with the following code:
import React, { useEffect } from 'react';
import DocumentViewerPackage from '@txtextcontrol/tx-react-document-viewer';
const DocumentViewer = DocumentViewerPackage.default ?? DocumentViewerPackage;
function App() {
useEffect(() => {
window.addEventListener('documentViewerLoaded', handleLoaded);
}, []);
const handleLoaded = (event) => {
var html = "<html><p>This is a document</p></html>";
var base64 = btoa(html);
event.srcElement['TXDocumentViewer'].loadDocument(base64, "loaded.html");
};
return (
<DocumentViewer
width="1000px"
height="800px"
basePath="https://localhost:7275">
</DocumentViewer>
);
}
export default App;
The handler takes the TXDocumentViewer instance from the source element of the event arguments, the window object, instead of using an undeclared global variable. The second parameter of loadDocument is the document name that the viewer displays.
To load a document from a Web API or another URL, download it in the handler first and pass the Base64-encoded result to loadDocument.
Load a Selected Document in TypeScript
If the document is already available on the client, you can load it whenever the user selects it. In a TypeScript project, declare TXDocumentViewer because it is a global JavaScript object. In a Vite project created with the TypeScript language, the following code replaces the content of src/main.tsx and loads the value of the selected option into the viewer:
import React from 'react';
import ReactDOM from 'react-dom/client';
import DocumentViewerPackage from '@txtextcontrol/tx-react-document-viewer';
const DocumentViewer = DocumentViewerPackage.default ?? DocumentViewerPackage;
declare var TXDocumentViewer: any;
const App: React.FC = () => {
const load = (contentValue: string) => {
if (TXDocumentViewer) {
// encode the content to base64
contentValue = btoa(contentValue);
// load the document into the viewer
TXDocumentViewer.loadDocument(contentValue, "loaded.html");
}
};
return <>
<select onChange={e => load(e.currentTarget.value)}>
<option>Select a Document</option>
<option value="Document <strong>#1</strong>">Document 1</option>
<option value="Document <strong>#2</strong>">Document 2</option>
<option value="Document <strong>#3</strong>">Document 3</option>
</select>
<br />
<br />
<DocumentViewer
width="800px"
height="500px"
basePath="https://localhost:7275"
isSelectionActivated={true}>
</DocumentViewer>
</>;
};
const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render(<App />);
The option values in this example are HTML strings. They can also contain Base64-encoded documents in other supported formats; in that case, pass them to loadDocument without calling btoa.
Next Steps
- JavaScript: more about the JavaScript API, including annotations and signatures.
- React npm Packages: the required React versions and both components in one project.
- Loading Documents: pass documents from a controller, load them at run time and show PDF files with PDF.js.
- Annotations: let users comment on and mark up documents.