useBlogLike
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
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
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()sendsPUT blogs/{id}/likeandremove()sendsDELETE blogs/{id}/unlike, both throughSalla.api.request.For a guest (
Salla.config.isGuest()),add()showsSalla.notify.errorwith the translationcommon.messages.must_loginand returns without a request.remove()has no guest check.Whether an article is liked is remembered only in
localStorageunderliked_blogs, read after mount. The API is never asked.countstarts atinitialCountand then changes only locally; it is never re-seeded from props.The engine's
BlogSinglePageuses it.
Gotchas
For a guest,
add()andtoggle()resolvetruealthough 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
blogIdorinitialCountdoes not resetcount. Give the component akeyper 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
A React key that goes up whenever a shopper posts a comment, so Salla's comments component reloads without a page refresh.
useAsyncFnWraps an async function with loading, error and value state; only the newest call updates state, and nothing updates after unmount.
Hook result typesShared shapes behind the action hooks: loading and error state, actions resolving to success, and the wishlist, like and coupon results.
Source and docs
- Engine source:
packages/theme-engine/src/hooks/useBlogLike.ts