{"id":15402,"library":"use-ssr","title":"React Hook for SSR Environment Detection","description":"The `use-ssr` package provides a lightweight React hook designed to detect the execution environment (server-side, browser, or React Native) within React components and hooks. Currently at version 1.0.25, this library offers a stable API for conditionally rendering or executing logic based on where the React application is running. It differentiates itself with zero runtime dependencies beyond React itself, comprehensive TypeScript support, and specific flags for React Native. The hook returns boolean flags (`isBrowser`, `isServer`, `isNative`) and an enum `device` string, along with capabilities like `canUseWorkers`, `canUseEventListeners`, and `canUseViewport`, making it versatile for isomorphic React applications. Its primary use case is in Universal or Server-Side Rendered (SSR) applications, such as those built with Next.js, where conditional logic based on the environment is critical for optimal performance and correct behavior.","status":"active","version":"1.0.25","language":"javascript","source_language":"en","source_url":"https://github.com/alex-cory/use-ssr","tags":["javascript","ssr","nextjs","server","server side rendering","server side","client","browser","isomorphic"],"install":[{"cmd":"npm install use-ssr","lang":"bash","label":"npm"},{"cmd":"yarn add use-ssr","lang":"bash","label":"yarn"},{"cmd":"pnpm add use-ssr","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency required for any React hook.","package":"react","optional":false},{"reason":"Peer dependency required for rendering React applications, especially in SSR contexts.","package":"react-dom","optional":false}],"imports":[{"note":"This package exports `useSSR` as its default export. Using named import syntax will result in an error in most bundlers/environments.","wrong":"import { useSSR } from 'use-ssr'","symbol":"useSSR","correct":"import useSSR from 'use-ssr'"}],"quickstart":{"code":"import React from 'react';\nimport useSSR from 'use-ssr';\n\nfunction App() {\n  const { isBrowser, isServer, isNative, device } = useSSR();\n\n  // This console log will show different results depending on the environment.\n  // In a browser: IS BROWSER: 👍, IS SERVER: 👎, IS NATIVE: 👎, DEVICE: browser\n  // On a server: IS BROWSER: 👎, IS SERVER: 👍, IS NATIVE: 👎, DEVICE: server\n  console.log('IS BROWSER: ', isBrowser ? '👍' : '👎');\n  console.log('IS SERVER: ', isServer ? '👍' : '👎');\n  console.log('IS NATIVE: ', isNative ? '👍' : '👎');\n  console.log('DEVICE: ', device);\n\n  return (\n    <div>\n      <h1>Environment Detection with useSSR</h1>\n      <p>Am I in a browser? {isBrowser ? 'Yes 👍' : 'No 👎'}</p>\n      <p>Am I on the server? {isServer ? 'Yes 👍' : 'No 👎'}</p>\n      <p>Am I in React Native? {isNative ? 'Yes 👍' : 'No 👎'}</p>\n      <p>Current device type: {device}</p>\n      {isBrowser && <p>This content only renders in the browser.</p>}\n      {isServer && <p>This content only renders on the server.</p>}\n    </div>\n  );\n}\n\n// To run this in a simple SSR setup (e.g., with Next.js or a custom server rendering),\n// you would integrate this App component into your server-side render function.\n// For a client-side only app, you'd render it directly to the DOM.\n// Example for a basic client-side render:\n// import ReactDOM from 'react-dom/client';\n// const root = ReactDOM.createRoot(document.getElementById('root'));\n// root.render(<App />);\nexport default App;\n","lang":"typescript","description":"Demonstrates how to import and use the `useSSR` hook to detect the current runtime environment (browser, server, or React Native) and conditionally render UI."},"warnings":[{"fix":"Ensure `useSSR()` is called unconditionally at the top level of your functional components or custom hooks, adhering strictly to React's Rules of Hooks.","message":"Like all React Hooks, `useSSR` must be called consistently within the render phase of a functional component or another custom hook. Violating the Rules of Hooks (e.g., calling it conditionally or outside a React function component) will lead to errors.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure that components that depend on `useSSR` for conditional rendering produce identical HTML on both server and client for the initial render, or manage hydration carefully. For example, use `useEffect` for browser-specific side effects that shouldn't impact initial server-rendered HTML, or utilize React's `suppressHydrationWarning` for minor, intentional mismatches.","message":"When using `useSSR` to conditionally render content in an SSR application, be mindful of hydration mismatches. If the server renders one version of HTML (e.g., based on `isServer`) and the client attempts to hydrate with different content (e.g., based on `isBrowser`) before the client-side JavaScript takes over, React may issue a hydration warning or re-render the entire component tree on the client, potentially impacting performance and SEO.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always gate access to browser-specific APIs using the `isBrowser` flag returned by `useSSR`, or perform such access within `useEffect` hooks which only run on the client. For example, `if (isBrowser) { /* access window/document */ }` or inside `useEffect(() => { /* access window/document */ }, [isBrowser])`.","message":"While `useSSR` correctly identifies the environment, directly accessing global browser-specific objects (like `window`, `document`, `localStorage`) outside of effects or `useSSR`'s returned flags in server-rendered components will still cause 'ReferenceError: window is not defined' errors during SSR.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Refactor your code to ensure `useSSR` is invoked only within the top level of a functional React component or a custom hook, following React's Rules of Hooks.","cause":"The `useSSR` hook was called outside of a functional React component or another custom hook.","error":"Error: Invalid hook call. Hooks can only be called inside of the body of a function component."},{"fix":"Wrap any code that accesses `window`, `document`, or other browser-only globals within a conditional check using `isBrowser` from `useSSR`, or within a `useEffect` hook. Example: `if (isBrowser) { window.alert('Hello'); }` or `useEffect(() => { if (isBrowser) { console.log(window.innerWidth); } }, [isBrowser]);`.","cause":"Browser-specific global objects like `window` or `document` were accessed in code that executed on the server-side.","error":"ReferenceError: window is not defined"},{"fix":"Ensure `useSSR` is imported as a default export: `import useSSR from 'use-ssr';`. This package exports `useSSR` as a default, not a named export.","cause":"Attempting to named-import `useSSR` when it is a default export, or a bundler configuration issue preventing correct module resolution.","error":"TypeError: Cannot destructure property 'isBrowser' of 'useSSR(...)' as it is undefined."}],"ecosystem":"npm"}