Link Access Check

Before a message is sent, checks each cloud document link against its recipients, so nobody gets a link they can't open and nothing goes public by accident.

StopsShared a link they can't open

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/link-access-check.json

The files land in your project. They're yours to edit.

Usage

link-access-check-usage.tsx
import { LinkAccessCheck, type DocLink, type LinkAccess, type LinkFix, type Recipient } from "@/components/ui/link-access-check"

<LinkAccessCheck text={text} recipients={recipients} orgDomains={["acme.com"]} checkAccess={checkAccess} delay={150} onFix={onFix} returnFocusRef={bodyRef} onSend={() => setSent(true)} />

What it catches

  • Recipients who can't open a linked document
  • Anyone-with-the-link documents going to people outside your domains
  • Links you can't re-share: suggests asking the owner
  • Links to the same document in different URL forms (?usp=sharing, /edit, /view) are treated as one

Props

LinkAccessCheck props
PropTypeDefault
text* (required)

The message body. Links to Google Drive, OneDrive/SharePoint, Dropbox, Notion, Figma and Box are found in it.

string—
recipients* (required)

Everyone the message goes to.

(Recipient | string)[]—
orgDomains

Your organisation's domains. Subdomains match too.

string[][]
checkAccess* (required)

Reads a link's sharing for these recipients from your storage API. Aborted when the input changes.

(link: DocLink, recipients: Recipient[], options: { signal: AbortSignal }) => Promise<LinkAccess>—
onFix

Applies a fix. Resolve with the new access, or nothing to have the link checked again.

(fix: LinkFix) => Promise<LinkAccess | void> | LinkAccess | void—
extraHosts

More hosts to treat as cloud docs, e.g. { "files.acme.com": "box" }.

Record<string, DocProvider>—
delay

Pause after typing before checking, in ms.

number500
onSend

Called on Send. With problems left the first click jumps to them and the second sends.

() => void | Promise<void>—
returnFocusRef

Where focus goes once the last fix is done, usually the message body.

React.RefObject<HTMLElement | null>—
messages

Any visible string.

Partial<LinkAccessMessages>—

* required. Also accepts the native props of <div> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Announcements go to a polite live region
  • Focus moves to the first fix, then to Send
  • Loading and retry states have text, with icons aria-hidden

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

This is a UX guard rail. Enforce on the server: Check sharing permissions with each provider's API on the server; never trust the client's view of who can open a document.

  • Relies on your checkAccess function to ask each storage API; it can't see permissions itself
  • Only recognises the listed hosts plus extraHosts
  • Group memberships are only as accurate as your API's answer

What it stops

Shared a link they can't open

Also known as

google drive · share link · permissions · request access · notion · figma · dropbox · onedrive

Field type

Dependencies

Pairs well with