VizStats UI
Hooks

useShareButton

Custom hook to share links

Setup


Create a new file called useShareButton.ts in your hooks directory: hooks/useShareButton.ts

import { useState, useCallback } from "react";
import { usePathname, useSearchParams } from "next/navigation";
 
export function useShareButton() {
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const [isCopied, setIsCopied] = useState(false);
 
  const rootUrl = process.env.NEXT_PUBLIC_ROOT_URL;
 
  const link =
    searchParams.toString() === ""
      ? `${rootUrl}${pathname}`
      : `${rootUrl}${pathname}?${searchParams.toString()}`;
 
  const copyToClipboard = useCallback(async () => {
    try {
      await navigator.clipboard.writeText(link);
      setIsCopied(true);
      // Reset the copied state after a short delay
      setTimeout(() => setIsCopied(false), 2000);
    } catch (error) {
      console.error("Failed to copy: ", error);
    }
  }, [link]);
 
  return {
    link,
    isCopied,
    copyToClipboard,
  };
}

Usage


Import the hook

import { useShareButton } from "@/hooks/useShareButton";

Use the hook

const { link, isCopied, copyToClipboard } = useShareButton();
 
return (
  <div className="flex items-center space-x-2">
    <div className="grid flex-1 gap-2">
      <Label htmlFor="link" className="sr-only">
        Link
      </Label>
      <Input id="link" defaultValue={link} readOnly />
    </div>
    <Button type="submit" size="sm" className="px-3" onClick={copyToClipboard}>
      <span className="sr-only">Copy</span>
      <CopyIcon className="h-4 w-4" />
    </Button>
    {isCopied && <span className="text-sm text-muted-foreground">Copied!</span>}
  </div>
);

Props

NameTypeDefaultDescription
linkstring""The link to be shared
isCopiedbooleanfalseWhether the link has been copied
copyToClipboard() => Promise<void>() => {}Function to copy the link to the clipboard

On this page