├── public ├── robots.txt ├── favicon.ico ├── document.pdf ├── another-example.pdf ├── manifest.json └── index.html ├── src ├── index.js ├── setupTests.js ├── App.test.js ├── index.css ├── App.css ├── App.js └── components │ └── PdfViewerComponent.js ├── scripts ├── copy-nutrient-files.js └── verify-install.js ├── .gitignore ├── package.json ├── LICENSE └── README.md /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PSPDFKit/pspdfkit-web-example-react/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/document.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PSPDFKit/pspdfkit-web-example-react/HEAD/public/document.pdf -------------------------------------------------------------------------------- /public/another-example.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PSPDFKit/pspdfkit-web-example-react/HEAD/public/another-example.pdf -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { createRoot } from "react-dom/client"; 2 | 3 | import "./index.css"; 4 | import App from "./App"; 5 | 6 | const root = createRoot(document.getElementById("root")); 7 | 8 | root.render(); 9 | -------------------------------------------------------------------------------- /scripts/copy-nutrient-files.js: -------------------------------------------------------------------------------- 1 | const ncp = require("ncp").ncp; 2 | 3 | ncp( 4 | "./node_modules/@nutrient-sdk/viewer/dist/nutrient-viewer-lib", 5 | "./public/nutrient-viewer-lib", 6 | (err) => { 7 | err && console.error(err); 8 | } 9 | ); 10 | -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import "@testing-library/jest-dom"; 6 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from "@testing-library/react"; 2 | import App from "./App"; 3 | 4 | test("renders learn react link", () => { 5 | render(); 6 | 7 | const linkElement = screen.getByText(/learn react/i); 8 | 9 | expect(linkElement).toBeInTheDocument(); 10 | }); 11 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 5 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 6 | sans-serif; 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | } 10 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | display: flex; 4 | flex-direction: column; 5 | height: 100vh; 6 | overflow: hidden; 7 | } 8 | 9 | .App-button { 10 | border: 0; 11 | display: block; 12 | width: 100%; 13 | background: rgb(97, 139, 224); 14 | color: white; 15 | font-size: 1.2em; 16 | padding: 0.5em; 17 | } 18 | 19 | .App-viewer { 20 | position: relative; 21 | flex: 1; 22 | } 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | public/pspdfkit-lib 26 | public/nutrient-viewer-lib 27 | -------------------------------------------------------------------------------- /scripts/verify-install.js: -------------------------------------------------------------------------------- 1 | try { 2 | require("@nutrient-sdk/viewer"); 3 | } catch (error) { 4 | if (!/cannot find module/i.test(error.message)) { 5 | return; 6 | } 7 | console.log( 8 | `This application requires you to install Nutrient Web SDK manually using your unique customer or trial url. 9 | For further instructions please refer to our online guide available at: 10 | 11 | https://www.nutrient.io/guides/web/current/standalone/adding-to-your-project#toc_install-with-npm` 12 | ); 13 | process.exit(1); 14 | } 15 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | 3 | import PdfViewerComponent from "./components/PdfViewerComponent"; 4 | import "./App.css"; 5 | 6 | function App() { 7 | const [document, setDocument] = useState("document.pdf"); 8 | 9 | const handleOpen = () => setDocument("another-example.pdf"); 10 | 11 | return ( 12 |
13 | 16 |
17 | 18 |
19 |
20 | ); 21 | } 22 | 23 | export default App; 24 | -------------------------------------------------------------------------------- /src/components/PdfViewerComponent.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from "react"; 2 | 3 | export default function PdfViewerComponent(props) { 4 | const containerRef = useRef(null); 5 | 6 | useEffect(() => { 7 | const container = containerRef.current; 8 | let PSPDFKit; 9 | 10 | (async function () { 11 | PSPDFKit = await import("@nutrient-sdk/viewer"); 12 | await PSPDFKit.load({ 13 | // Container where PSPDFKit should be mounted. 14 | container, 15 | // The document to open. 16 | document: props.document, 17 | // Use the public directory URL as a base URL. PSPDFKit will download its library assets from here. 18 | baseUrl: `${window.location.protocol}//${window.location.host}/${process.env.PUBLIC_URL}`, 19 | }); 20 | })(); 21 | 22 | return () => PSPDFKit && PSPDFKit.unload(container); 23 | }, [props.document]); 24 | 25 | return
; 26 | } 27 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 16 | 17 | 26 | Nutrient Web SDK Example – React.js 27 | 28 | 29 | 30 |
31 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pspdfkit-web-example-react", 3 | "version": "1.0.0", 4 | "description": "Standalone and offline PDF viewer web application built with Nutrient Web SDK and React", 5 | "keywords": [ 6 | "wasm", 7 | "web", 8 | "assembly", 9 | "pdf", 10 | "pdf", 11 | "viewer", 12 | "react", 13 | "asm.js", 14 | "offline", 15 | "indexeddb" 16 | ], 17 | "author": "PSPDFKit (https://www.nutrient.io)", 18 | "homepage": "https://www.nutrient.io", 19 | "license": "SEE LICENSE IN https://www.nutrient.io/legal/Nutrient_SDK_User_Evaluation_Subscription_Agreement", 20 | "readme": "https://www.nutrient.io/guides/web", 21 | "dependencies": { 22 | "@nutrient-sdk/viewer": "1.1.0", 23 | "@testing-library/jest-dom": "^5.16.3", 24 | "@testing-library/react": "^13.0.0", 25 | "@testing-library/user-event": "^14.0.4", 26 | "react": "^18.0.0", 27 | "react-dom": "^18.0.0", 28 | "react-scripts": "^5.0.1" 29 | }, 30 | "scripts": { 31 | "verify-installation": "node scripts/verify-install.js && node scripts/copy-nutrient-files.js", 32 | "prestart": "npm run verify-installation", 33 | "start": "react-scripts start", 34 | "prebuild": "npm run verify-installation", 35 | "build": "react-scripts build", 36 | "test": "react-scripts test", 37 | "eject": "react-scripts eject" 38 | }, 39 | "devDependencies": { 40 | "cross-env": "^7.0.2", 41 | "ncp": "^2.0.0" 42 | }, 43 | "browserslist": [ 44 | "Firefox ESR", 45 | "last 2 Chrome versions", 46 | "last 2 firefox versions", 47 | "last 2 edge versions", 48 | "last 2 safari versions", 49 | "last 2 and_chr versions", 50 | "last 2 ios_saf versions" 51 | ], 52 | "overrides": { 53 | "nth-check": "^2.0.1", 54 | "minimatch": "^3.0.5", 55 | "loader-utils": "^2.0.4", 56 | "json5": "^2.2.2", 57 | "postcss": "^8.4.31", 58 | "rollup": "^3.29.5", 59 | "cross-spawn": "^7.0.5", 60 | "express": "^4.21.2" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The PSPDFKit Sample applications are licensed with a modified BSD 2 | license. In plain language: you're allowed to do whatever you wish 3 | with the code, modify, redistribute, embed in your products (free or 4 | commercial), but you must include copyright, terms of usage and 5 | disclaimer as stated in the license. 6 | 7 | You will require a commercial PSPDFKit License to run these examples 8 | in non-demo mode. Please refer to sales@nutrient.io for details. 9 | 10 | Copyright © 2017-present PSPDFKit GmbH. 11 | All rights reserved. 12 | 13 | Redistribution and use in source or binary forms, 14 | with or without modification, are permitted provided 15 | that the following conditions are met: 16 | 17 | - Redistributions of source code must retain the above copyright 18 | notice, this list of conditions and the following disclaimer. 19 | 20 | - Redistributions in binary form must reproduce the above copyright 21 | notice, this list of conditions and the following disclaimer in the 22 | documentation and/or other materials provided with the 23 | distribution. 24 | 25 | - Redistributions of PSPDFKit Samples must include attribution to 26 | PSPDFKit, either in documentation or other appropriate media. 27 | 28 | - Neither the name of the PSPDFKit, PSPDFKit GmbH, nor its developers 29 | may be used to endorse or promote products derived from 30 | this software without specific prior written permission. 31 | 32 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 35 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 37 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 38 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 39 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 40 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 41 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 42 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > ⚠️ **Repository Moved** 2 | > This repository has been moved to https://github.com/PSPDFKit/nutrient-web-examples/tree/main/examples/react. 3 | > Please update your bookmarks and issues accordingly. 4 | > 5 | > This repo is now archived and will no longer receive updates. 6 | 7 | ## Nutrient Web SDK Example — React.js 8 | 9 | Nutrient Web SDK is a powerful PDF SDK that enables you to view, annotate, sign, and edit PDF documents in your web applications. This repository demonstrates how to seamlessly integrate PSPDFKit with a React application. 10 | 11 | ## Features 12 | 13 | - **View and Annotate PDFs** — Easily view and annotate PDF documents within your web app. 14 | - **Real-Time Collaboration** — Sync document edits, text highlights, and annotations across Android, iOS, and web devices in real time. 15 | - **Electronic and Digital Signatures** — Certified, encrypted, and secure document signing workflows. 16 | - **Forms** — Create, fill, capture, and submit PDF form data. 17 | - **Cross-Platform** — Consistent behavior across different web browsers. 18 | 19 | ## Prerequisites 20 | 21 | - [Node.js][] 22 | 23 | ## Support and Issues 24 | 25 | Are you evaluating our SDK? That’s great, and we’re happy to help! Feel free to contact our [Sales team][sales] to schedule a demo. 26 | 27 | ## Getting Started 28 | 29 | Clone the repository: 30 | 31 | ```bash 32 | git clone https://github.com/PSPDFKit/pspdfkit-web-example-react.git 33 | cd pspdfkit-web-example-react 34 | ``` 35 | 36 | Install the project dependencies with npm: 37 | 38 | ```bash 39 | npm install 40 | ``` 41 | 42 | If you need more information, refer to our [Getting Started on Web][getting started] guide. 43 | 44 | ## Running the Example 45 | 46 | Now you’re ready to launch the app! 🎉 47 | 48 | Run the app in development mode: 49 | 50 | ```bash 51 | npm start 52 | ``` 53 | 54 | Create a production build of the app and serve it: 55 | 56 | ```bash 57 | npm run build 58 | npx serve -s build 59 | ``` 60 | 61 | Enjoy! 🍕 62 | 63 | ## React Component 64 | 65 | The React component that implements the Nutrient Web SDK integration can be found at `src/components/PdfViewerComponent`. 66 | 67 | To make the files above available, copy them from the `node_modules/@nutrient-sdk/viewer/dist` folder using the script at `scripts/copy-nutrient-files`. 68 | 69 | ## License 70 | 71 | This software is licensed under a [modified BSD license](LICENSE). 72 | 73 | ## FAQ 74 | 75 | ### How Do I Integrate PSPDFKit with My Existing React App? 76 | 77 | Follow [this guide][react existing project] to integrate our Web SDK into your project. 78 | 79 | ### Where Can I Find More Documentation? 80 | 81 | We have extensive documentation with [developer guides for React][react guides] that show you how to add document functionality to React apps. 82 | 83 | ## Useful Resources 84 | 85 | - [How to Convert HTML to PDF Using React][] 86 | - [How to Build a React.js PDF Viewer with react-pdf][] 87 | 88 | ## Contributing 89 | 90 | Please ensure you’ve signed [our CLA][cla] so that we can accept your contributions. 91 | 92 | [node.js]: http://nodejs.org/ 93 | [sales]: https://www.nutrient.io/sdk/contact-sales 94 | [getting started]: https://www.nutrient.io/getting-started/web/?frontend=react&download=npm&integration=module 95 | [react existing project]: https://www.nutrient.io/getting-started/web/?frontend=react&project=existing-project 96 | [react guides]: https://www.nutrient.io/guides/web/react/ 97 | [how to convert html to pdf using react]: https://www.nutrient.io/blog/2022/how-to-convert-html-to-pdf-using-react/ 98 | [how to build a react.js pdf viewer with react-pdf]: https://www.nutrient.io/blog/2021/how-to-build-a-reactjs-pdf-viewer-with-react-pdf/ 99 | [cla]: https://www.nutrient.io/guides/web/current/miscellaneous/contributing/ 100 | --------------------------------------------------------------------------------