File size: 1,827 Bytes
6111b2b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
"use client";

import { useEffect, useState } from "react";

export const DEFAULT_DISPLAY_BASE_URL = "http://localhost:20128";

function normalizeUrl(value?: string): string | null {
  const trimmed = value?.trim();
  if (!trimmed) return null;
  return trimmed.replace(/\/+$/, "");
}

/**

 * Returns the public base URL to display in the dashboard.

 *

 * Resolution chain:

 *   1. NEXT_PUBLIC_BASE_URL (env, trimmed + slash-normalized) — wins if set.

 *   2. window.location.origin after client mount — when env is unset.

 *   3. DEFAULT_DISPLAY_BASE_URL ("http://localhost:20128") — SSR / first render fallback.

 *

 * DISPLAY ONLY — do NOT use this hook for OAuth `redirect_uri`.

 * OAuth callers must read `process.env.NEXT_PUBLIC_BASE_URL` directly to avoid

 * host-header attack surface. For server-side resolution, use

 * `src/shared/utils/resolveOmniRouteBaseUrl.ts` instead.

 */
export function useDisplayBaseUrl(): string {
  const envValue = normalizeUrl(process.env.NEXT_PUBLIC_BASE_URL);

  const [url, setUrl] = useState<string>(envValue ?? DEFAULT_DISPLAY_BASE_URL);

  useEffect(() => {
    if (envValue) return;
    const origin = normalizeUrl(window.location.origin) ?? DEFAULT_DISPLAY_BASE_URL;
    // Schedule via queueMicrotask so setState is called inside a callback,
    // not synchronously in the effect body (react-hooks/set-state-in-effect).
    // The unmounted guard prevents a stale setState on a torn-down root
    // (relevant under React strict mode's double-invoke, where cleanup runs
    // before the microtask fires on the first effect invocation).
    let unmounted = false;
    queueMicrotask(() => {
      if (!unmounted) setUrl(origin);
    });
    return () => {
      unmounted = true;
    };
  }, [envValue]);

  return url;
}