Skip to content

Hydrogen 2025.7.0, entry.server.tsx doesn't work, (ReferenceError: require is not defined) #18089

Description

@necheporenko

Is there an existing issue for this?

How do you use Sentry?

Sentry Saas (sentry.io)

Which SDK are you using?

@sentry/cloudflare

SDK Version

^10.22.0

Framework Version

React 18.3.1

Link to Sentry event

No response

Reproduction Example/SDK Setup

Here is my code:

package.json:

{
  "name": "project-name",
  "private": true,
  "sideEffects": false,
  "version": "2025.7.0",
  "type": "module",
  "scripts": {
    "build": "shopify hydrogen build --codegen",
    "dev": "shopify hydrogen dev --codegen",
    "preview": "shopify hydrogen preview --build",
    "lint": "eslint --no-error-on-unmatched-pattern .",
    "typecheck": "react-router typegen && tsc --noEmit",
    "codegen": "shopify hydrogen codegen && react-router typegen"
  },
  "prettier": "@shopify/prettier-config",
  "dependencies": {
    "@algolia/requester-fetch": "^4.25.2",
    "@headlessui/react": "^2.2.9",
    "@okendo/shopify-hydrogen": "^2.5.3",
    "@portabletext/react": "^3.2.1",
    "@sanity/image-url": "^1.2.0",
    "@sanity/webhook": "^4.0.4",
    "@sentry/cloudflare": "^10.22.0",
    "@sentry/react-router": "^10.22.0",
    "@shopify/hydrogen": "2025.7.0",
    "@tailwindcss/forms": "^0.5.10",
    "@tailwindcss/typography": "^0.5.19",
    "@tailwindcss/vite": "^4.1.15",
    "@typeform/embed-react": "^4.6.0",
    "algoliasearch": "^4.25.2",
    "clsx": "^2.1.1",
    "disqus-react": "^1.1.7",
    "get-youtube-id": "^1.0.1",
    "graphql": "^16.10.0",
    "graphql-tag": "^2.12.6",
    "hydrogen-sanity": "^5.1.0",
    "isbot": "^5.1.22",
    "lodash.debounce": "^4.0.8",
    "lucide-react": "^0.539.0",
    "react": "18.3.1",
    "react-currency-input-field": "^3.10.0",
    "react-dom": "18.3.1",
    "react-instantsearch": "^7.16.3",
    "react-portable-text": "^0.6.0",
    "react-router": "7.9.2",
    "react-router-dom": "7.9.2",
    "react-slider": "^2.0.6",
    "react-use": "^17.6.0",
    "swiper": "^11.2.10",
    "tailwind-merge": "^3.3.1",
    "tailwindcss": "^4.1.15",
    "yet-another-react-lightbox": "^3.25.0"
  },
  "devDependencies": {
    "@eslint/compat": "^1.2.5",
    "@eslint/eslintrc": "^3.2.0",
    "@eslint/js": "^9.18.0",
    "@graphql-codegen/cli": "5.0.2",
    "@react-router/dev": "7.9.2",
    "@react-router/fs-routes": "7.9.2",
    "@shopify/cli": "3.85.4",
    "@shopify/hydrogen-codegen": "^0.3.3",
    "@shopify/mini-oxygen": "^4.0.0",
    "@shopify/oxygen-workers-types": "^4.1.6",
    "@shopify/prettier-config": "^1.1.2",
    "@total-typescript/ts-reset": "^0.6.1",
    "@types/eslint": "^9.6.1",
    "@types/lodash.debounce": "^4.0.9",
    "@types/react": "^18.2.22",
    "@types/react-dom": "^18.2.7",
    "@types/react-slider": "^1.3.6",
    "@typescript-eslint/eslint-plugin": "^8.21.0",
    "@typescript-eslint/parser": "^8.21.0",
    "eslint": "^9.18.0",
    "eslint-config-prettier": "^10.0.1",
    "eslint-import-resolver-typescript": "^3.7.0",
    "eslint-plugin-eslint-comments": "^3.2.0",
    "eslint-plugin-import": "^2.31.0",
    "eslint-plugin-jest": "^28.11.0",
    "eslint-plugin-jsx-a11y": "^6.10.2",
    "eslint-plugin-react": "^7.37.4",
    "eslint-plugin-react-hooks": "^5.1.0",
    "eslint-plugin-simple-import-sort": "^12.1.1",
    "globals": "^15.14.0",
    "prettier": "^3.4.2",
    "typescript": "^5.9.2",
    "vite": "^6.2.4",
    "vite-tsconfig-paths": "^4.3.1"
  },
  "engines": {
    "node": ">=18.0.0"
  },
  "browserslist": [
    "defaults"
  ]
}

instrument.server.mjs:

import * as Sentry from '@sentry/react-router';

Sentry.init({
  dsn: 'MY DSN LINK',
  // Adds request headers and IP for users, for more info visit:
  // https://docs.sentry.io/platforms/javascript/guides/react-router/configuration/options/#sendDefaultPii
  sendDefaultPii: true,
  tracesSampleRate: 1.0,
});

app/entry.client.tsx:

import {startTransition, StrictMode} from 'react';
import {hydrateRoot} from 'react-dom/client';
import {HydratedRouter} from 'react-router/dom';
import {NonceProvider} from '@shopify/hydrogen';

import * as Sentry from '@sentry/react-router/cloudflare';

Sentry.init({
  dsn: 'MY DSN LINK',
  integrations: [Sentry.reactRouterTracingIntegration()],
  tracesSampleRate: 1.0,
});

if (!window.location.origin.includes('webcache.googleusercontent.com')) {
  startTransition(() => {
    // Extract nonce from existing script tags
    const existingNonce =
      document.querySelector<HTMLScriptElement>('script[nonce]')?.nonce;

    hydrateRoot(
      document,
      <StrictMode>
        <NonceProvider value={existingNonce}>
          <HydratedRouter />
        </NonceProvider>
      </StrictMode>,
    );
  });
}

server.ts:

// Virtual entry point for the app
import {storefrontRedirect} from '@shopify/hydrogen';
import {createRequestHandler} from '@shopify/hydrogen/oxygen';

import {wrapRequestHandler} from '@sentry/cloudflare/request';

import {createHydrogenRouterContext} from '~/lib/context';

/**
 * Export a fetch handler in module format.
 */
export default {
  async fetch(
    request: Request,
    env: Env,
    executionContext: ExecutionContext,
  ): Promise<Response> {
    try {
      return wrapRequestHandler(
        {
          options: {
            dsn: 'MY DSN LINK',
            tracesSampleRate: 1.0,
          },
          request: request as any,
          context: executionContext,
        },
        async () => {
          const hydrogenContext = await createHydrogenRouterContext(
            request,
            env,
            executionContext,
          );

          /**
           * Create a Remix request handler and pass
           * Hydrogen's Storefront client to the loader context.
           */
          const handleRequest = createRequestHandler({
            // eslint-disable-next-line import/no-unresolved
            build: await import('virtual:react-router/server-build'),
            mode: process.env.NODE_ENV,
            getLoadContext: () => hydrogenContext,
          });

          const response = await handleRequest(request);

          if (hydrogenContext.session.isPending) {
            response.headers.set(
              'Set-Cookie',
              await hydrogenContext.session.commit(),
            );
          }

          if (response.status === 404) {
            /**
             * Check for redirects only when there's a 404 from the app.
             * If the redirect doesn't exist, then `storefrontRedirect`
             * will pass through the 404 response.
             */
            return storefrontRedirect({
              request,
              response,
              storefront: hydrogenContext.storefront,
            });
          }

          return response;
        },
      );
    } catch (error) {
      console.error(error);
      return new Response('An unexpected error occurred', {status: 500});
    }
  },
};

vite.config.ts:

import {reactRouter} from '@react-router/dev/vite';
import {hydrogen} from '@shopify/hydrogen/vite';

import {sentryReactRouter} from '@sentry/react-router';
import {oxygen} from '@shopify/mini-oxygen/vite';
import tailwindcss from '@tailwindcss/vite';
import {sanity} from 'hydrogen-sanity/vite';
import {defineConfig} from 'vite';
import tsconfigPaths from 'vite-tsconfig-paths';

export default defineConfig((config) => ({
  plugins: [
    tailwindcss(),
    hydrogen(),
    oxygen(),
    reactRouter(),
    sentryReactRouter(
      {
        org: 'MY ORG',
        project: 'MY PROJECT',
        authToken:  'MY AUTH TOKEN',
      },
      config,
    ),
    tsconfigPaths(),
    sanity(),
  ],
  build: {
    // Allow a strict Content-Security-Policy
    // withtout inlining assets as base64:
    assetsInlineLimit: 0,
  },
  ssr: {
    optimizeDeps: {
      /**
       * Include dependencies here if they throw CJS<>ESM errors.
       * For example, for the following error:
       *
       * > ReferenceError: module is not defined
       * >   at /Users/.../node_modules/example-dep/index.js:1:1
       *
       * Include 'example-dep' in the array below.
       * @see https://vitejs.dev/config/dep-optimization-options
       */
      include: [
        'react-portable-text',
        '@headlessui/react',
        'algoliasearch',
        'react-instantsearch',
        'disqus-react',
        'set-cookie-parser',
        'cookie',
        'react-router',
      ],
    },
  },
  server: {
    allowedHosts: true,
  },
}));

app/entry.server.tsx:

import {renderToReadableStream} from 'react-dom/server';
import type {EntryContext} from 'react-router';
import {ServerRouter} from 'react-router';
import {
  createContentSecurityPolicy,
  type HydrogenRouterContextProvider,
} from '@shopify/hydrogen';

import {isbot} from 'isbot';

export default async function handleRequest(
  request: Request,
  responseStatusCode: number,
  responseHeaders: Headers,
  reactRouterContext: EntryContext,
  context: HydrogenRouterContextProvider,
) {
  const {SanityProvider} = context.sanity;
  const {nonce, header, NonceProvider} = createContentSecurityPolicy({
    shop: {
      checkoutDomain: context.env.PUBLIC_CHECKOUT_DOMAIN,
      storeDomain: context.env.PUBLIC_STORE_DOMAIN,
    },
    imgSrc: ['*'],
    styleSrc: ['*', 'unsafe-inline'],
    fontSrc: ['*', 'data:'],
    defaultSrc: ['*'],
    scriptSrc: ['*', 'unsafe-inline', "'strict-dynamic'"],
    connectSrc: ["'self'", '*'],
  });

  const body = await renderToReadableStream(
    <NonceProvider>
      <SanityProvider>
        <ServerRouter
          context={reactRouterContext}
          url={request.url}
          nonce={nonce}
        />
      </SanityProvider>
    </NonceProvider>,
    {
      nonce,
      signal: request.signal,
      onError(error) {
        console.error(error);
        responseStatusCode = 500;
      },
    },
  );

  if (isbot(request.headers.get('user-agent'))) {
    await body.allReady;
  }

  responseHeaders.set('Content-Type', 'text/html');
  responseHeaders.set('Content-Security-Policy', header);

  return new Response(body, {
    headers: responseHeaders,
    status: responseStatusCode,
  });
}

Steps to Reproduce

In my code, I use the correct DSN, project, org, authToken, and everything works fine except for app/entry.server.tsx.

I'm trying to follow this step (https://docs.sentry.io/platforms/javascript/guides/cloudflare/frameworks/hydrogen-react-router/# server-side-rendering-with-trace-injection), but here (app/entry.server.tsx.), if I insert import '../ instrument.server.mjs'; or start using anything from here import * as Sentry from “@sentry/react-router/cloudflare”;, I get an error:

ReferenceError: require is not defined
    at /Users/PATH/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js:3:15
    at Object.runInlinedModule (Users/PATH/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1418:17)
    at ModuleRunner.directRequest (Users/PATH/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1281:82)
    at ModuleRunner.cachedRequest (Users/PATH/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1176:28)
    at request (Users/PATH/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1225:79)
    at /Users/PATH/node_modules/@sentry/react/build/esm/hoist-non-react-statics.js?v=bab08d99:2:31
    at Object.runInlinedModule (Users/PATH/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1418:11)
    at ModuleRunner.directRequest (Users/PATH/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1281:61)
    at ModuleRunner.cachedRequest (Users/PATH/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1177:79)
    at /Users/PATH/node_modules/@sentry/react/build/esm/profiler.js?v=bab08d99:7:365

Expected Result

Working app/entry.server.tsx part

Actual Result

ERROR:

ReferenceError: require is not defined
    at /Users/PATH/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js:3:15
    at Object.runInlinedModule (Users/PATH/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1418:17)
    at ModuleRunner.directRequest (Users/PATH/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1281:82)
    at ModuleRunner.cachedRequest (Users/PATH/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1176:28)
    at request (Users/PATH/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1225:79)
    at /Users/PATH/node_modules/@sentry/react/build/esm/hoist-non-react-statics.js?v=bab08d99:2:31
    at Object.runInlinedModule (Users/PATH/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1418:11)
    at ModuleRunner.directRequest (Users/PATH/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1281:61)
    at ModuleRunner.cachedRequest (Users/PATH/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1177:79)
    at /Users/PATH/node_modules/@sentry/react/build/esm/profiler.js?v=bab08d99:7:365

Additional Context

I have already tried different versions of Node.js (https://sentry.io/answers/next-js-referenceerror-request-is-not-defined-reading-old-version-of-node/), and tried removing "type": "module" from package.json, but to no avail.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions