Skip to content
useElementPageContext Organization

The useElementPageContext hook provides a function to add custom elements to a PDF page.

It enables you to create custom elements such as a bounding box, a shape or an image for a specified page.

This is useful for labelling certain parts of a PDF page or displaying certain content dynamically.

NameTypeDescription
updateElement(pageNumber: number, element: (dimension: {width: number, height: number}, rotate: number, zoom: number) => HTMLElement | JSX.Element) => voidAdd a custom element to the specific page
removeElement(pageNumber: number, index: number) => voidRemove a custom element from the specific page
clearElements(pageNumber: number) => voidRemove all custom elements from the specific page
elementListRecord<number, Array<HTMLElement | JSX.Element>>Access the current scale level of the current PDF page

To ensure the element page context can be accessed, you will need to use useElementPageContext inside a component which is a child of RPProvider.

This example shows how to create a CustomElementPage component which uses useElementPageContext to handle the element page functionality.

import { useCallback, useState, useEffect } from 'react'
import {
RPConfig,
RPProvider,
RPDefaultLayout,
RPPages,
useElementPageContext
} from '@pdf-viewer/react'
const createHTMLElement = (
id,
scale,
{ x, y } = { x: 0, y: 0 }
) => {
const div = document.createElement('div')
// set id to element
div.id = id
// setting style
div.style.backgroundColor = 'green'
div.style.width = `${100 * scale}px`
div.style.height = `${100 * scale}px`
div.style.color = 'white'
div.style.padding = '2px 4px'
div.style.borderRadius = '4px'
div.style.position = 'absolute'
// set position
div.style.top = y * scale + 'px'
div.style.left = x * scale + 'px'
return div
}
// function to create react jsx element
const createJSXElement = (
id,
removeElement,
scale: number
) => {
return (
<div
id={id}
style={{
backgroundColor: 'red',
width: `${100 * scale}px`,
height: `${100 * scale}px`,
color: 'white',
padding: '2px 4px',
borderRadius: '4px',
position: 'absolute',
// set position
top: '0px',
left: '50px',
zIndex: 10
}}
>
<button onClick={() => removeElement(1, 1)}>remove</button>
</div>
)
}
const CustomElement = () => {
const { updateElement, removeElement, clearElements } = useElementPageContext()
const [page, setPage] = useState(1)
const [x, setX] = useState(0)
const [y, setY] = useState(0)
const [list, setList] = useState({})
useEffect(() => {
const pages = Object.keys(list)
// list element
Object.entries(list).forEach(([page, items]) => {
items.forEach((item, idx) => {
updateElement(Number(page), (_prev = [], _dimension, _rotate, scale) => {
return [
..._prev,
createHTMLElement(`${page}-${idx}`, scale / 100, { x: item.x, y: item.y })
]
})
})
})
// base element
updateElement(1, (_prev = [], _dimension, _rotate, scale) => {
return [
..._prev,
// HTML element
createHTMLElement('1', scale / 100),
// JSX element
createJSXElement('2', removeElement, scale / 100)
]
})
return () => {
pages.forEach((page) => {
clearElements(Number(page))
})
clearElements(1)
}
}, [updateElement, list, removeElement, clearElements])
const handleClear = useCallback(() => {
setList((prev) => {
const newList = { ...prev }
delete newList[page]
return newList
})
}, [page])
const handleAdd = useCallback(() => {
setList((prev) => ({
...prev,
[page]: [
...(prev[page] || []),
{
x,
y
}
]
}))
}, [page, x, y])
return (
<>
<div>
page: <input type="number" value={page} onChange={(e) => setPage(Number(e.target.value))} />
</div>
<div>
x: <input type="number" value={x} onChange={(e) => setX(Number(e.target.value))} />
</div>
<div>
y: <input type="number" value={y} onChange={(e) => setY(Number(e.target.value))} />
</div>
<button onClick={handleClear}>clear</button>
<button onClick={handleAdd}>add</button>
</>
)
}
export const AppPdfViewer = () => {
return (
<RPConfig licenseKey="YOUR_LICENSE_KEY">
<RPProvider src="https://cdn.codewithmosh.com/image/upload/v1721763853/guides/web-roadmap.pdf">
<CustomElement />
<RPDefaultLayout>
<RPPages />
</RPDefaultLayout>
</RPProvider>
</RPConfig>
)
}

An example of how to use useElementPageContext hook