COMING SOON: Fall 2024 Release

How to Build a Cross-Platform PDF Viewer with React and React Native

By Shirley Gong | 2020 Oct 14

Sanity Image
Read time

3 min

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 Apryse SDK and expo.

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

Cross-platform PDF viewer with React and React Native

Setup

Copied to clipboard

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 the detailed getting started guide from React Native for Web.

Integrate with Apryse SDK

Copied to clipboard

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

Interested in learning more on WebViewer? Check out our comprehensive guide here.

Native

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

expo eject

Follow the instructions to add Apryse's React Native module to the app. Follow all of the cross-platform instructions. Then, follow step 1-5 for Android, and step 1-3 for iOS.

Android

Create a local.properties file inside the android folder with your Android SDK location, for example:

ndk.dir=/Users/<user-name>/Library/Android/sdk/ndk-bundle
sdk.dir=/Users/<user-name>/Library/Android/sdk

Note: Replace with your actual path.

Web

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

Then, add the following to package.json:

"scripts": {
  "postinstall": "node tools/copy-webviewer-files.js"
},

Lastly, create a tools folder, and add the following copy-webviewer-files.js file in it: https://github.com/PDFTron/webviewer-react-sample/tree/master/tools

Create the PDF Viewer

Copied to clipboard

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
  • package.json - exports the component

Add the following to the package.json:

{
  "name": "Viewer",
  "version": "0.0.0",
  "private": true,
  "main": "./Viewer"
}

Native 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;

WebViewer

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;

Use the PDF Viewer

Copied to clipboard

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!

Conclusion

Copied to clipboard

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

Get started with Apryse 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.

Sanity Image

Shirley Gong

Share this post

email
linkedIn
twitter