#1717·SurfSense

[Bug] Frontend SSR fails with `ReferenceError: document is not defined`

Author: Ianfr13Created Aug 25, 2026Updated Aug 25, 2026

Summary

The production frontend intermittently fails during server-side rendering because browser-only code accesses document while the application is being evaluated on the server.

This results in an unhandled server-side rejection and can prevent the page or chat response from rendering correctly.

Environment

  • Project: SurfSense
  • Deployment platform: Railway
  • Environment: Production
  • Frontend framework: Next.js
  • Next.js version shown in logs: 16.2.12
  • Frontend deployment: 81a32cb9-4493-4c76-9b4d-d1737d50dbbc
  • Approximate occurrence: 2026-08-25 00:29 UTC

Production logs

ReferenceError: document is not defined
    at <unknown> (.next/server/chunks/ssr/app_1lmx4fc._.js:1:79752)
    at <unknown> (.next/server/chunks/ssr/app_1lmx4fc._.js:1:118732)
    at module evaluation (.next/server/chunks/ssr/app_1lmx4fc._.js:1:118738)
    ...

⨯ unhandledRejection: ReferenceError: document is not defined

Actual behavior

  • The Next.js server evaluates a module that references document.
  • The server throws ReferenceError: document is not defined.
  • The error is reported as an unhandledRejection.
  • The page may fail to render, hydrate incorrectly, or show a chat interface that appears to stop responding.
  • The production stack trace only points to the minified SSR chunk, so the exact source module has not yet been identified.

Expected behavior

  • Server-side rendering should complete without accessing browser-only globals.
  • The initial page should load and hydrate successfully.
  • Chat messages and streamed model responses should render normally.
  • Browser-only APIs such as document, window, and navigator should only be accessed on the client.

Additional evidence

The backend was still successfully processing chat requests while the frontend error occurred.

Backend logs showed successful chat streams, successful finalization, and completed tool calls during the same period. This indicates that at least some user reports of the model “stopping” may actually be caused by the frontend failing to render or hydrate the response, rather than by the model/provider failing.

Steps to reproduce

  1. Deploy the frontend to Railway production.
  2. Open the SurfSense application.
  3. Load a dashboard or chat page that uses SSR.
  4. Ask a question that produces a streamed response.
  5. Inspect the frontend deployment logs.
  6. Observe ReferenceError: document is not defined.

The issue appeared in production after deployment. A subsequent update/redeploy made the problem stop reproducing, but the underlying regression should still be tracked.

Suspected cause

A client-only module or code path is being evaluated during SSR/module initialization and accesses document before the browser exists.

The production stack is minified and does not expose the original source file. Source maps or a local reproduction with the same build should be used to identify the exact module.

Suggested investigation

  • Reproduce using the same production build with server source maps enabled.
  • Search for browser-global access occurring:
    • at module scope;
    • during render;
    • inside shared utilities imported by server components;
    • inside code that is not explicitly client-only.
  • Verify all usages of:
    • document;
    • window;
    • navigator;
    • localStorage;
    • sessionStorage.
  • Check whether the affected module should:
    • be moved into useEffect;
    • be guarded with a browser check;
    • be marked as a client component;
    • be dynamically imported with SSR disabled.

Acceptance criteria

  • No ReferenceError: document is not defined appears in production logs.
  • No unhandledRejection is generated by frontend SSR.
  • Initial page rendering succeeds after a cold start.
  • Client hydration succeeds without console errors.
  • A streamed chat response is displayed correctly.
  • A regression test or SSR smoke test covers the affected code path.