useNavigatorShare

NEW

React hook to share content through the browser.

Add the hook via the CLI:

npx @novajslabs/cli add useNavigatorShare

Or copy and paste the code into your project:

interface IShareData {
  title: string
  text: string
  url?: string
  files?: File[]
}

const errorMessages: Record<string, string> = {
  NotAllowedError: 'Permission to share denied.',
  AbortError: 'The sharing action was aborted.',
  NotSupportedError: 'Your browser does not support the sharing feature.',
  TypeError: 'Error while sharing: incorrect data type.',
}

function checkPermission(files?: File[]) {
  if (!navigator.canShare) {
    throw new Error('Your browser does not support the sharing feature.')
  }

  if (!navigator.canShare({ files } || { files: [new File([], '')] })) {
    throw new Error(
      `Your browser does not allow sharing ${
        files ? 'this type of ' : ''
      } files.`,
    )
  }
}

function surroundTryCatch(fn: (data: IShareData) => void | Promise<void>) {
  return async (data: IShareData) => {
    try {
      await fn(data)
    } catch (error: unknown) {
      if ((error as Error).name in errorMessages) {
        const message = `Error while sharing: ${
          errorMessages[(error as Error).name]
        }`
        console.error(message)
      } else {
        throw error
      }
    }
  }
}

export const useNavigatorShare = () => {
  async function shareInNavigator(data: IShareData) {
    if (data.files) checkPermission(data.files)

    await navigator.share({
      title: data.title,
      text: data.text ?? '',
      url: data.url ?? '',
      files: data.files ?? [],
    })
  }

  return {
    shareInNavigator: surroundTryCatch(shareInNavigator),
  }
}

React 16.8 or higher

  • Name
    shareInNavigator
    Type
    function
    Description

    Triggers the sharing process using the provided data.

  • shareInNavigator parameters

    • Name
      title
      Type
      string
      Required
      required
      Description

      The title of the content to share.

    • Name
      text
      Type
      string
      Required
      required
      Description

      The text message to share.

    • Name
      url
      Type
      string
      Optional
      optional
      Description

      A URL to share.

    • Name
      files
      Type
      File[]
      Optional
      optional
      Description

      An array of files to share.

import { useNavigatorShare } from './hooks/useNavigatorShare'

const App = () => {
  const { shareInNavigator } = useNavigatorShare()

  const handleShare = async () => {
    const shareData = {
      title: 'Check this out!',
      text: 'This is a cool link you should visit.',
      url: 'https://novajs.co',
      files: [
        new File(['Nova.js is amazing!'], 'example.txt', {
          type: 'text/plain',
        }),
      ],
    }

    try {
      await shareInNavigator(shareData)
      alert('File shared successfully!')
    } catch (error) {
      console.error(error)
      alert('There was an error trying to share the file.')
    }
  }

  return <button onClick={handleShare}>Share</button>
}

export default App

Here are some use cases where this React hook is useful:

  • Sharing an article from a news website
  • Sharing images from a gallery app
  • Sharing a product page from an e-commerce site
  • Sharing a document from a file management system
  • Sharing an event invitation