Skip to main content
React hooks for creating and managing shareable links for goals, allowing public or permission-based access. Fetch all active share links for a goal.
const { data, isLoading, error } = useShareLinks(goalId)

Parameters

goalId
string
required
The ID of the goal to fetch share links for

Returns

data
ShareLink[]
Array of active (non-revoked) share links for the goal
isLoading
boolean
Loading state of the query
error
Error | null
Error object if the query failed

Example

import { useShareLinks } from '@features/goals/api/use-share-links'

function ShareLinksList({ goalId }: { goalId: string }) {
  const { data: shareLinks, isLoading } = useShareLinks(goalId)
  
  if (isLoading) return <div>Loading...</div>
  
  return (
    <ul>
      {shareLinks?.map((link) => (
        <li key={link.id}>
          Token: {link.token} - Permission: {link.permission}
        </li>
      ))}
    </ul>
  )
}
Create a new share link for a goal.
const { mutate, mutateAsync, isPending } = useCreateShareLink()

Returns

mutate
(params: CreateShareLinkParams) => void
Function to create a share link
mutateAsync
(params: CreateShareLinkParams) => Promise<ShareLink>
Async function to create a share link and await the result
isPending
boolean
Loading state of the mutation

Parameters

goalId
string
required
The ID of the goal to create a share link for
permission
SharePermission
required
The permission level for the share link. Possible values: 'view', 'comment', 'edit'

Example

import { useCreateShareLink } from '@features/goals/api/use-share-links'

function CreateShareLinkButton({ goalId }: { goalId: string }) {
  const { mutate: createShareLink, isPending } = useCreateShareLink()
  
  const handleCreate = (permission: SharePermission) => {
    createShareLink(
      { goalId, permission },
      {
        onSuccess: (link) => {
          const url = `${window.location.origin}/shared/${link.token}`
          navigator.clipboard.writeText(url)
          alert('Link copied to clipboard!')
        },
      }
    )
  }
  
  return (
    <div>
      <button onClick={() => handleCreate('view')} disabled={isPending}>
        Create View Link
      </button>
      <button onClick={() => handleCreate('comment')} disabled={isPending}>
        Create Comment Link
      </button>
      <button onClick={() => handleCreate('edit')} disabled={isPending}>
        Create Edit Link
      </button>
    </div>
  )
}
Revoke an existing share link.
const { mutate, mutateAsync, isPending } = useRevokeShareLink()

Returns

mutate
(params: RevokeShareLinkParams) => void
Function to revoke a share link
mutateAsync
(params: RevokeShareLinkParams) => Promise<string>
Async function to revoke a share link and await completion. Returns the goal ID.
isPending
boolean
Loading state of the mutation

Parameters

id
string
required
The ID of the share link to revoke
goalId
string
required
The ID of the goal (used for cache invalidation)

Example

import { useRevokeShareLink } from '@features/goals/api/use-share-links'

function RevokeShareLinkButton({
  linkId,
  goalId,
}: {
  linkId: string
  goalId: string
}) {
  const { mutate: revokeLink, isPending } = useRevokeShareLink()
  
  const handleRevoke = () => {
    if (confirm('Revoke this share link? It will no longer be accessible.')) {
      revokeLink({ id: linkId, goalId })
    }
  }
  
  return (
    <button onClick={handleRevoke} disabled={isPending}>
      Revoke Link
    </button>
  )
}

useGoalByToken

Fetch a goal using a share link token.
const { data, isLoading, error } = useGoalByToken(token)

Parameters

token
string
required
The share link token to use for fetching the goal

Returns

data
ShareLink & { goal: Goal }
The share link object with the associated goal data included
isLoading
boolean
Loading state of the query
error
Error | null
Error object if the query failed (e.g., invalid or revoked token)

Example

import { useGoalByToken } from '@features/goals/api/use-share-links'
import { useParams } from 'react-router-dom'

function SharedGoalPage() {
  const { token } = useParams<{ token: string }>()
  const { data, isLoading, error } = useGoalByToken(token!)
  
  if (isLoading) return <div>Loading...</div>
  if (error) return <div>Invalid or expired share link</div>
  
  return (
    <div>
      <h1>{data?.goal.title}</h1>
      <p>Permission: {data?.permission}</p>
      <p>{data?.goal.description}</p>
    </div>
  )
}

Build docs developers (and LLMs) love