Skip to content
Twilight React Playground
ثيم رائدaren

useBlogLike

hookBeginnerserverbrowserlive demo

Likes or unlikes a blog article through the Salla API, with a local like count and a per-browser memory of liked articles.

import { useBlogLike, UseBlogLikeResult } from '@salla.sa/twilight-theme-engine/hooks/useBlogLike';

In plain words

This is the thumbs-up on a blog article. toggle() likes the article, or unlikes it if it was liked, and count goes up or down. active tells you whether this browser already liked it.

Only logged-in customers can like; a guest gets Salla's "please log in" message.

Signature

function useBlogLike(blogId: number, initialCount?: number): UseBlogLikeResult  // initialCount 0

type UseBlogLikeResult = UseToggle;
// {
//   active: boolean;  count: number;
//   add / remove / toggle: () => Promise<boolean>;
//   loading: boolean;  error: string | null;
// }

Try it live

A like button for a real article of the demo store. Guests are asked to log in and no request is sent.Try this: press the button: as a guest you get the "log in" notice, count stays the same, and yet toggle() resolves true.
Real requests to the demo store
Storefront canvas · en · LTR
active: false · loading: false · error: null
Controls
What a theme writes
import { useBlogLike } from '@salla.sa/twilight-theme-engine/hooks/useBlogLike';

export function LikeButton() {
  const { active, count, toggle, loading } = useBlogLike(1673272609, 3);
  return (
    <button aria-pressed={active} disabled={loading} onClick={() => void toggle()}>
      <i className="sicon-thumbs-up" /> {count}
    </button>
  );
}

Example

app/components/blog/LikeButton.tsx
import { useBlogLike } from '@salla.sa/twilight-theme-engine/hooks/useBlogLike';

export function LikeButton({ articleId, likes }: { articleId: number; likes: number }) {
  const { active, count, toggle, loading } = useBlogLike(articleId, likes);

  return (
    <button type="button" aria-pressed={active} disabled={loading} onClick={() => void toggle()}>
      <i className="sicon-thumbs-up" /> {count}
    </button>
  );
}

// Render one per article, keyed by it: <LikeButton key={article.id} ... />

How it behaves

  • add() sends PUT blogs/{id}/like and remove() sends DELETE blogs/{id}/unlike, both through Salla.api.request.

  • For a guest (Salla.config.isGuest()), add() shows Salla.notify.error with the translation common.messages.must_login and returns without a request. remove() has no guest check.

  • Whether an article is liked is remembered only in localStorage under liked_blogs, read after mount. The API is never asked.

  • count starts at initialCount and then changes only locally; it is never re-seeded from props.

  • The engine's BlogSinglePage uses it.

Gotchas

  • For a guest, add() and toggle() resolve true although nothing was liked: returning early is not an error.

  • Each call keeps its own copy of the liked list and writes the whole copy back to localStorage (on mount too). Two instances on one page overwrite each other and can erase earlier likes. Render one per page, as the engine does.

  • A changed blogId or initialCount does not reset count. Give the component a key per article so it starts fresh.

  • The server renders active: false; it flips after mount, and a like made in another browser never shows as active.

Related

Source and docs