Selection Plugin
The Selection Plugin enables users to select text within the PDF document, just like on a standard webpage. It provides the <SelectionLayer /> to visually highlight the selected text and a rich API to get the selected content.
Installation
This plugin depends on the Interaction Manager plugin. You must install both packages.
npm install @embedpdf/plugin-selection @embedpdf/plugin-interaction-managerRegistration
Import SelectionPluginPackage and its InteractionManager dependency, and add them to the plugins array. The Selection plugin should be registered after its dependency.
import { createPluginRegistration } from '@embedpdf/core'
// ... other imports
import { InteractionManagerPluginPackage } from '@embedpdf/plugin-interaction-manager/svelte'
import { SelectionPluginPackage } from '@embedpdf/plugin-selection/svelte'
const plugins = [
// ... other essential plugins
createPluginRegistration(DocumentManagerPluginPackage, { /* ... */ }),
// Register dependency first
createPluginRegistration(InteractionManagerPluginPackage),
// Register the selection plugin
createPluginRegistration(SelectionPluginPackage),
]Usage
The plugin has two main parts: the <SelectionLayer /> component for the UI, and the useSelectionCapability store for interacting with the selection data.
1. Displaying the Selection
To show the highlighted text, place the <SelectionLayer /> component inside the renderPage snippet of your <Scroller />. For text selection to work correctly, it must be a child of the PagePointerProvider.
Both components require the documentId to link to the correct document state.
<script lang="ts">
import { PagePointerProvider } from '@embedpdf/plugin-interaction-manager/svelte';
import { SelectionLayer } from '@embedpdf/plugin-selection/svelte';
let { documentId }: { documentId: string } = $props();
</script>
{#snippet renderPage(page)}
<PagePointerProvider {documentId} pageIndex={page.pageIndex}>
<RenderLayer {documentId} pageIndex={page.pageIndex} />
<SelectionLayer {documentId} pageIndex={page.pageIndex} />
</PagePointerProvider>
{/snippet}
<Scroller {documentId} {renderPage} />2. Interacting with the Selection
The useSelectionCapability store allows you to work with the selected text. You need to scope the capability to the specific document using .forDocument(id).
You can use the onSelectionChange event to know when a selection exists, which is useful for enabling or disabling UI elements like a “Copy” button.
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import { useSelectionCapability, type SelectionRangeX } from '@embedpdf/plugin-selection/svelte';
let { documentId }: { documentId: string } = $props();
const selectionCapability = useSelectionCapability();
let hasSelection = $state(false);
let unsubscribe: (() => void) | undefined;
onMount(() => {
const selection = selectionCapability.provides?.forDocument(documentId);
unsubscribe = selection?.onSelectionChange((sel: SelectionRangeX | null) => {
hasSelection = !!sel;
});
});
onDestroy(() => unsubscribe?.());
const handleCopy = () => {
selectionCapability.provides?.forDocument(documentId).copyToClipboard();
};
</script>
<button onclick={handleCopy} disabled={!hasSelection}>Copy</button>3. Adding a Selection Menu
You can display a contextual menu near the selected text—perfect for a “Copy” button that appears inline. Use the selectionMenuSnippet snippet on <SelectionLayer />. The placement prop provides hints about whether to position the menu above or below the selection.
<script lang="ts">
import { SelectionLayer, useSelectionCapability } from '@embedpdf/plugin-selection/svelte';
let { documentId }: { documentId: string } = $props();
const selectionCapability = useSelectionCapability();
const handleCopy = () => {
const scope = selectionCapability.provides?.forDocument(documentId);
scope?.copyToClipboard();
scope?.clear(); // Clear selection after copying
};
</script>
<SelectionLayer {documentId} pageIndex={page.pageIndex}>
{#snippet selectionMenuSnippet({ rect, menuWrapperProps, placement })}
<span style={menuWrapperProps.style} use:menuWrapperProps.action>
<div
style:position="absolute"
style:top={placement.suggestTop ? '-48px' : `${rect.size.height + 8}px`}
style:pointer-events="auto"
style:cursor="default"
>
<button onclick={handleCopy}>Copy</button>
</div>
</span>
{/snippet}
</SelectionLayer>The menuWrapperProps provides a style string and an action for your wrapper element—the style handles positioning relative to page rotation, while the action handles event propagation to prevent interaction conflicts with underlying layers.
Live Example
Try selecting text in the viewer below. A contextual “Copy” menu will appear near your selection, and the toolbar’s “Copy Text” button will become active. This demonstrates both the selectionMenu snippet and the useSelectionCapability store.
API Reference
Configuration (SelectionPluginConfig)
| Option | Type | Description |
|---|---|---|
menuHeight | number | The approximate height of the selection menu in pixels. Used to determine whether to show the menu above or below the selection. Default: 40 |
Component: <SelectionLayer />
The component that renders the blue rectangles over the selected text.
| Prop | Type | Description |
|---|---|---|
documentId | string | (Required) The ID of the document. |
pageIndex | number | (Required) The index of the page this layer is on. |
background | string | (Optional) The color of the selection highlight. Default: 'rgba(33,150,243)' |
selectionMenu | Snippet | (Optional) A snippet to render a contextual menu near the selection. |
Snippet: selectionMenuSnippet
| Prop | Type | Description |
|---|---|---|
rect | Rect | The bounding box of the selection. |
menuWrapperProps | MenuWrapperProps | An object containing style: string for positioning and action: Action to attach to your wrapper element via use:menuWrapperProps.action. |
placement | object | An object with suggestTop: boolean to help position the menu above or below the selection. |
Store: useSelectionCapability()
Connects your component to the selection plugin’s API.
Returns
| Property | Type | Description |
|---|---|---|
provides | SelectionCapability | null | The selection API object. |
SelectionCapability Methods
| Method | Description |
|---|---|
forDocument(id) | Returns a SelectionScope for the specified document ID. |
SelectionScope Methods (Returned by forDocument)
| Method | Description |
|---|---|
copyToClipboard() | Triggers the process to copy the currently selected text to the user’s clipboard. |
clear() | Clears the current selection. |
getSelectedText() | Returns a Task<string[]> that resolves with the selected text content. Each string in the array is a line. |
getFormattedSelection() | Returns an array of objects describing the selection on each page, including its bounding box and the individual highlight rectangles. |
onSelectionChange | An event hook that fires when the text selection is created, updated, or cleared. |
onEndSelection | An event hook that fires when the user finishes selecting text (on mouse up). This is ideal for fetching the selected text content. |
Need Help?
Join our community for support, discussions, and to contribute to EmbedPDF's development.