useNavigatorShare
React hook to share content through the browser.
Add the hook via the CLI:
sh
npx @novajslabs/cli add useNavigatorShare
sh
npx @novajslabs/cli add useNavigatorShare
sh
pnpm dlx @novajslabs/cli add useNavigatorShare
Or copy and paste the code into your project:
ts
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),
};
};
js
const errorMessages = {
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) {
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) {
return async (data) => {
try {
await fn(data);
} catch (error) {
if (error.name in errorMessages) {
const message = `Error while sharing: ${errorMessages[error.name]}`;
console.error(message);
} else {
throw error;
}
}
};
}
export const useNavigatorShare = () => {
async function shareInNavigator(data) {
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),
};
};
Requirements
React 16.8 or higher
Return values
shareInNavigator
Type: function
Parameters:
ts
interface IShareData {
title: string;
text: string;
url?: string;
files?: File[];
}
Triggers the sharing process using the provided data.
Example
tsx
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;
Use cases
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