React Native is an open source framework for building native mobile apps using JavaScript. Being a popular choice for mobile apps, it compiles the JavaScript components into native components to provide users with the fluid look and feel of traditional native applications. It is possible to create a cross-platform application with React Native and React that will run on both native and the web. With learn-once-write-anywhere in mind, it is more efficient for developers to create cross-platform applications with a single codebase and have it work on native and the web. This speeds up development, creates consistent UX, while still has the option to maintain the flexibility for platform-specific logic.

In this tutorial, you will learn how to create a cross-platform PDF viewer with React and React Native using PDFTron SDK and expo.

By the end of this tutorial, you will be able to build something like this:

linkSetup

First, let's create a simple expo app:

npm install react react-dom react-native-web
npm install expo-cli --global
expo init my-app
cd my-app
expo start

This will create an app that can work on native and the web. See detailed getting started guide from React Native for Web.

linkIntegrate with PDFTron SDK

Next, we will add PDFTron's React Native SDK as well as WebViewer into the app.

linkNative

PDFTron's React Native SDK is a native module, therefore, we will first need to eject the native modules:

expo eject

Then, follow the instructions here to add PDFTron's React Native module to the app. Follow step 1-5 for Android, and step 1-3 for iOS.

linkWeb

Follow the instructions here to add WebViewer to the app. Follow step 1-2.

linkCreate the PDF Viewer

Create a components/viewer folder, then add the following files:

  • Viewer.native.tsx - the native implementation of the viewer
  • Viewer.tsx - the web implementation of the viewer

linkNative Viewer

Add in Viewer.native.tsx:

import React from 'react';
import {useEffect} from 'react';

import { DocumentView, RNPdftron } from 'react-native-pdftron';

type ViewerProps = {
  document: string
}

const MyComponent = ({ document }: ViewerProps) => {

  useEffect(() => {
    RNPdftron.initialize("Insert commercial license key here after purchase");
  }, []);

  return (
    <DocumentView
      document={document}
      padStatusBar
    />
  );
};

export default MyComponent;

linkWebViewer

Add in Viewer.tsx:

import React from 'react';
import {useEffect, useRef} from 'react';
import WebViewer from '@pdftron/webviewer';

type ViewerProps = {
  document: string
}

const MyComponent = ({ document }: ViewerProps) => {
  const viewer = useRef<HTMLDivElement>(null);

  useEffect(() => {
    WebViewer(
      {
        path: 'lib',
        initialDoc: document,
      },
      viewer.current as HTMLDivElement,
    ).then((instance) => {
        // you can now call WebViewer APIs here...
      });
  }, []);

  return (
    <div className="MyComponent">
      <div className="webviewer" ref={viewer} style={{height: "100vh"}}></div>
    </div>
  );
};

export default MyComponent;

linkUse the PDF Viewer

In App.tsx, this viewer component can now be used:

return (
  <View style={styles.container}>
    <MyViewer document={"https://pdftron.s3.amazonaws.com/downloads/pl/PDFTRON_about.pdf"}/>
  </View>
);

This will pick up the native component on the mobile and the WebViewer component on the web. The rest of your application can share the same code, both for business logic and the UI.

That's it!

You can find full source code from https://github.com/PDFTron/pdftron-react-and-react-native-sample.

linkConclusion

As you can see, create a cross-platform PDF viewer that runs on both the mobile and the web using PDFTron SDK isn’t too complicated when using PDFTron's React-Native SDK, WebViewer and expo.

Get started with PDFTron for React Native and WebViewer and let us know what you build!

We hope you found this article helpful! If you have any questions or comments, don’t hesitate to contact us.