• בלוג
  • היום למדתי: פקודת browser ב next.js

היום למדתי: פקודת browser ב next.js

07/09/2026

כשלמדתי next.js לקח לי זמן להבין שכשאני כותב use client בתחילת קובץ הכוונה שלהם היא שהקוד ירוץ גם ב client וגם ב server, ולא רק ב client כמו שאולי היה אפשר להבין מהשם.

למעשה בעבודה עם ריאקט ו next הרצת קוד רק בדפדפן תמיד היתה קצת מסורבלת. הנה מה שקלוד הדפיס כשביקשתי ממנו לכתוב קומפוננטה ל next שקוראת ערך ששמור ב local storage ומדפיסה אותו:

'use client';

import { useEffect, useState } from 'react';

export default function StoredValue({ storageKey = 'username', fallback = 'Not set' }) {
  // null means "haven't read storage yet" — distinct from an empty stored value
  const [value, setValue] = useState(null);

  useEffect(() => {
    try {
      setValue(localStorage.getItem(storageKey) ?? fallback);
    } catch {
      // Storage can throw in private mode or when disabled
      setValue(fallback);
    }
  }, [storageKey, fallback]);

  if (value === null) return <p>Loading…</p>;

  return <p>{value}</p>;
}

בשביל לקרוא מ local storage ריאקט היה צריך להחביא את הקוד שקורא מקוד צד השרת שיריץ אותו, כי על השרת ה local storage אולי לא זמין ובטוח מכיל ערכים אחרים.

לאחרונה next הוסיפו מנגנון חמוד בשם browser: https://react.dev/reference/react-dom/browser

המטרה שלו לאפשר לסמן קוד שירוץ רק בדפדפן ולא על השרת. כן, כאילו הוא מוסתר באפקט רק בלי כל הטקס. הנה הגרסה המודרנית של אותו קוד:

'use client';

import { use, useState } from 'react';
import { browser } from 'react-dom';

export default function StoredValue({ storageKey = 'username', fallback = 'Not set' }) {
  use(browser('The value is stored in localStorage.'));

  const [value] = useState(() => localStorage.getItem(storageKey) ?? fallback);

  return <p>{value}</p>;
}

המלכודת היחידה בעדכון היא לכתוב את הקומפוננטה רק בתוך Suspense Boundary כלומר:

import { Suspense } from 'react';
import StoredValue from './StoredValue';

export default function Page() {
  return (
    <Suspense fallback={<p>Loading…</p>}>
      <StoredValue />
    </Suspense>
  );
}

אבל בטח יש לכם אחד כזה ביישום כבר בשביל כל הפיצ'רים האחרים שבנויים עליו.