← Files WixARCHIVED FILE

skills/wix-headless-templates/portfolio/app/hooks/portfolio/useProjectDetail.ts

1.3 KB · Oct 8, 2026 · 12:02 UTC

↓ Download file

See the change to this file →

// React binding of the project-detail store (wix/portfolio/project-detail-store.ts) — slug →
// project + media gallery lives there, framework-free; this hook subscribes to one instance per
// (slug, mount) and recreates it when the slug changes. SSR-friendly: pass both `initial*` and no
// client fetch happens. `notFound` is the real not-found signal (project stays null while loading).
import { useEffect, useRef, useSyncExternalStore } from "react";
import {
  createProjectDetailStore,
  type ProjectDetailState,
  type ProjectDetailStore,
  type ProjectDetailStoreOptions,
} from "../../wix/portfolio/project-detail-store";

export type UseProjectDetailOptions = ProjectDetailStoreOptions;

export type UseProjectDetail = ProjectDetailState;

export function useProjectDetail(
  slug: string,
  { initialProject, initialItems }: UseProjectDetailOptions = {},
): UseProjectDetail {
  const ref = useRef<{ slug: string; store: ProjectDetailStore } | null>(null);
  if (!ref.current || ref.current.slug !== slug) {
    ref.current = { slug, store: createProjectDetailStore(slug, { initialProject, initialItems }) };
  }
  const store = ref.current.store;
  useEffect(() => {
    store.start();
    return () => store.stop();
  }, [store]);
  return useSyncExternalStore(store.subscribe, store.getState, store.getState);
}

SHA-256: f7cc5b4bc5850943ecc1dec5621c499e266669150ba1a4a2036fe253c0f6657a