Skip to content

Conversation

Oksamies
Copy link
Contributor

@Oksamies Oksamies commented Aug 26, 2025

Apparently the Vite env variables are not available in loaders or SSR in
general. So we have to use the process instead on server side code.

Summary by CodeRabbit

  • Bug Fixes

    • Unified server/client domain resolution to avoid incorrect links and removed hardcoded fallback.
    • Fixed API host sourcing for server-side contexts to reduce connection issues.
    • Improved authentication redirect behavior with SSR-aware return URLs.
  • Chores

    • Standardized environment variable names (VITE_*) across app loaders, workflows, storybook, and CI tooling.

Copy link

coderabbitai bot commented Aug 26, 2025

Walkthrough

Switches many loaders to read DapperTs apiHost from process.env.VITE_API_URL instead of import.meta.env. Adds SSR-aware site and auth domain resolution in root and ThunderstoreAuth, and updates auth login/return URL construction. No exported/public signatures changed.

Changes

Cohort / File(s) Summary of changes
Loader apiHost env source updated
apps/cyberstorm-remix/app/c/community.tsx, apps/cyberstorm-remix/app/communities/communities.tsx, apps/cyberstorm-remix/app/p/dependants/Dependants.tsx, apps/cyberstorm-remix/app/p/packageEdit.tsx, apps/cyberstorm-remix/app/p/packageListing.tsx, apps/cyberstorm-remix/app/p/tabs/Changelog/Changelog.tsx, apps/cyberstorm-remix/app/p/tabs/Readme/Readme.tsx, apps/cyberstorm-remix/app/p/tabs/Required/Required.tsx, apps/cyberstorm-remix/app/p/tabs/Versions/Versions.tsx, apps/cyberstorm-remix/app/p/tabs/Wiki/Wiki.tsx, apps/cyberstorm-remix/app/p/tabs/Wiki/WikiFirstPage.tsx, apps/cyberstorm-remix/app/p/tabs/Wiki/WikiPage.tsx, apps/cyberstorm-remix/app/p/tabs/Wiki/WikiPageEdit.tsx, apps/cyberstorm-remix/app/p/team/Team.tsx, apps/cyberstorm-remix/app/upload/upload.tsx
In loaders, DapperTs apiHost now reads process.env.VITE_API_URL instead of import.meta.env.VITE_API_URL. No other logic or signatures changed.
SSR-aware site domain resolution
apps/cyberstorm-remix/app/root.tsx
Introduces SSR/CSR branching to compute domain from process.env.VITE_SITE_URL (SSR) or import.meta.env.VITE_SITE_URL (CSR); removes previous hardcoded/default fallback. Passes domain to layout and uses it as dapper config fallback.
SSR-aware auth base and return URL
apps/cyberstorm-remix/cyberstorm/utils/ThunderstoreAuth.tsx
Adds SSR/CSR branching to resolve domain/returnDomain from process.env.* (SSR) or import.meta.env.* (CSR). Login URL and default next use these computed domains (default next → ${returnDomain}/communities/).
CI / env var key alignment
.github/workflows/test.yml, tools/visual-diff-ci/run_ci_script.py, apps/cyberstorm-storybook/constants.ts
Renames/aligns environment variable keys to VITE_* (VITE_SITE_URL, VITE_API_URL, VITE_AUTH_BASE_URL, VITE_AUTH_RETURN_URL) and updates storybook constants to use process.env.VITE_*.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant App as Application
  participant Loader as Page Loader
  participant AuthUtil as ThunderstoreAuth
  participant AuthServer

  rect rgba(200,230,255,0.25)
    note over App: Runtime domain resolution
    App->>App: if SSR → domain = process.env.VITE_SITE_URL
    App->>App: if CSR → domain = import.meta.env.VITE_SITE_URL
  end

  User->>Loader: request page (loader)
  Loader->>Loader: init DapperTs(apiHost = process.env.VITE_API_URL)
  Loader->>App: fetch data via DapperTs
  App-->>User: render page

  User->>AuthUtil: initiate login(next?)
  rect rgba(220,255,220,0.25)
    AuthUtil->>AuthUtil: if SSR → base/return = process.env.VITE_AUTH_*
    AuthUtil->>AuthUtil: if CSR → base/return = import.meta.env.VITE_AUTH_*
    AuthUtil->>AuthServer: redirect to {base}/login?next={encode(next ?? return + "/communities/")}
  end

  AuthServer-->>User: auth flow / redirect back
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

I nibbled envs by lantern-light,
Swapped client whispers for server night.
Domains now know which side to play,
Auth paths hop home the proper way.
Ears up, I dance — URLs aligned today! 🐇✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 08-26-fix_env_variable_grabbing

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
apps/cyberstorm-remix/app/p/tabs/Wiki/WikiFirstPage.tsx (1)

21-22: Handle packages with zero wiki pages

wiki.pages[0] can be undefined; add a guard to return 404 or a friendly message.

-    const firstPage = await dapper.getPackageWikiPage(wiki.pages[0].id);
+    const firstPageId = wiki.pages[0]?.id;
+    if (!firstPageId) {
+      throw new Response("Wiki has no pages", { status: 404 });
+    }
+    const firstPage = await dapper.getPackageWikiPage(firstPageId);
apps/cyberstorm-remix/app/p/tabs/Wiki/WikiPage.tsx (1)

95-99: Off-by-one when determining nextPage

The last valid index is length - 1. As written, the last page still attempts to access pages[currentPageIndex + 1].

-    if (currentPageIndex === wiki.pages.length) {
+    if (currentPageIndex >= wiki.pages.length - 1) {
       nextPage = undefined;
     } else {
       nextPage = wiki.pages[currentPageIndex + 1]?.slug;
     }
apps/cyberstorm-remix/app/root.tsx (1)

214-218: Ensure API host fallback uses the API URL, not the site origin

The current code in apps/cyberstorm-remix/app/root.tsx (around lines 111–117 and 214–218) falls back to the site’s origin (VITE_SITE_URL) when config.apiHost is absent. However, all other client-side calls—including the session context in app/middlewares.ts—use VITE_API_URL as the API host. Falling back to the site URL can silently misroute API requests, leading to 404s or CORS errors.

  • In app/root.tsx:
    • Lines 113–116 define domain from VITE_SITE_URL (SSR vs. client).
    • Lines 214–218 use that domain when data.config.apiHost is missing.

Suggested change: derive a proper API host fallback from VITE_API_URL instead of VITE_SITE_URL. For example:

--- apps/cyberstorm-remix/app/root.tsx
@@ lines 111–117
- let domain: string;
- if (import.meta.env.SSR) {
-   domain = process.env.VITE_SITE_URL || "";
- } else {
-   domain = import.meta.env.VITE_SITE_URL;
- }
+ // Primary API host fallback
+ const apiFallback = import.meta.env.SSR
+   ? process.env.VITE_API_URL || ""
+   : import.meta.env.VITE_API_URL;
@@ lines 214–218
-   return {
-     apiHost: data ? data.config.apiHost : domain,
-     sessionId: data?.config.sessionId,
-   };
+   if (!data?.config.apiHost && !apiFallback) {
+     throw new Error("API host is not configured");
+   }
+   return {
+     apiHost: data?.config.apiHost ?? apiFallback,
+     sessionId: data?.config.sessionId,
+   };

By wiring VITE_API_URL as the fallback andsurfacing an error when no host is available, you prevent silent misrouting and make missing configuration explicit.

🧹 Nitpick comments (24)
apps/cyberstorm-remix/app/p/packageListing.tsx (1)

96-99: Meta og:url still uses import.meta.env; make it SSR-safe

meta() runs during SSR and on client transitions. Using import.meta.env here can be undefined on the server. Prefer a value computed server-side (via loader) and passed in data.

Apply this diff:

     {
       property: "og:url",
-      content: `${import.meta.env.VITE_SITE_URL}${location.pathname}`,
+      content: data?.siteUrl ? `${data.siteUrl}${location.pathname}` : location.pathname,
     },

And extend the loader to provide siteUrl (example):

// change signature to access request
export async function loader({ request, params }: LoaderFunctionArgs) {
  // ...
  const siteUrl = process.env.VITE_SITE_URL ?? new URL(request.url).origin;
  return {
    // existing props...
    siteUrl,
  };
}
apps/cyberstorm-remix/app/p/dependants/Dependants.tsx (1)

28-33: Provide a sane SSR fallback for apiHost using the request origin

Switch to process.env is correct. To harden SSR, fall back to the current origin if VITE_API_URL is not set. This keeps dev/staging resilient without masking misconfigurations.

   const dapper = new DapperTs(() => {
-    return {
-      apiHost: process.env.VITE_API_URL,
-      sessionId: undefined,
-    };
+    return {
+      apiHost: process.env.VITE_API_URL ?? new URL(request.url).origin,
+      sessionId: undefined,
+    };
   });
apps/cyberstorm-remix/app/p/tabs/Wiki/WikiPageEdit.tsx (1)

41-46: Add a guard for missing VITE_API_URL (or accept request and derive a fallback)

As written, a missing env will only surface during fetch. Prefer failing early; optionally also accept request to compute a safe default origin in development.

Fail-fast guard:

   const dapper = new DapperTs(() => {
-    return {
-      apiHost: process.env.VITE_API_URL,
-      sessionId: undefined,
-    };
+    const apiHost = process.env.VITE_API_URL;
+    if (!apiHost) {
+      throw new Response("Server misconfiguration: VITE_API_URL is not set", { status: 500 });
+    }
+    return { apiHost, sessionId: undefined };
   });

Alternatively, to add a fallback origin, adjust the signature and use request:

export async function loader({ request, params }: LoaderFunctionArgs) {
  const dapper = new DapperTs(() => ({
    apiHost: process.env.VITE_API_URL ?? new URL(request.url).origin,
    sessionId: undefined,
  }));
  // ...
}
apps/cyberstorm-remix/app/communities/communities.tsx (1)

69-74: SSR fallback for apiHost improves robustness in local/staging

Same pattern as other loaders: fall back to the current origin if the env is missing.

 const dapper = new DapperTs(() => {
   return {
-    apiHost: process.env.VITE_API_URL,
+    apiHost: process.env.VITE_API_URL ?? new URL(request.url).origin,
     sessionId: undefined,
   };
 });
apps/cyberstorm-remix/app/upload/upload.tsx (1)

71-76: Guard or fallback for apiHost in SSR loader

This route’s loader currently has no request param, so add a guard to fail fast on misconfiguration; optionally accept request to derive a fallback.

Guard-only fix:

 export async function loader() {
   // console.log("loader context", getSessionTools(context));
   const dapper = new DapperTs(() => {
-    return {
-      apiHost: process.env.VITE_API_URL,
-      sessionId: undefined,
-    };
+    const apiHost = process.env.VITE_API_URL;
+    if (!apiHost) {
+      throw new Response("Server misconfiguration: VITE_API_URL is not set", { status: 500 });
+    }
+    return { apiHost, sessionId: undefined };
   });
   return await dapper.getCommunities();
 }

Optional request-based fallback:

export async function loader({ request }: LoaderFunctionArgs) {
  const dapper = new DapperTs(() => ({
    apiHost: process.env.VITE_API_URL ?? new URL(request.url).origin,
    sessionId: undefined,
  }));
  return await dapper.getCommunities();
}
apps/cyberstorm-remix/app/p/tabs/Readme/Readme.tsx (1)

10-15: Reduce duplication: introduce a tiny server helper to instantiate DapperTs with SSR-safe apiHost

This pattern repeats across many loaders. Centralize it to keep env checks consistent.

Example helper (to add under e.g. apps/cyberstorm-remix/cyberstorm/server/dapper.ts):

import { DapperTs } from "@thunderstore/dapper-ts";

export function createServerDapper(sessionId?: string) {
  const raw = process.env.VITE_API_URL ?? "";
  if (!raw) throw new Error("VITE_API_URL is not set");
  const apiHost = raw.replace(/\/+$/, "");
  return new DapperTs(() => ({ apiHost, sessionId }));
}

Then here:

-      const dapper = new DapperTs(() => ({
-        apiHost,
-        sessionId: undefined,
-      }));
+      const dapper = createServerDapper();
apps/cyberstorm-remix/app/p/tabs/Required/Required.tsx (2)

14-19: Add runtime guard for VITE_API_URL and normalize base URL

Same rationale as other loaders: prevent undefined apiHost and avoid trailing-slash issues.

-      const dapper = new DapperTs(() => {
-        return {
-          apiHost: process.env.VITE_API_URL,
-          sessionId: undefined,
-        };
-      });
+      const rawApiHost = process.env.VITE_API_URL ?? "";
+      if (!rawApiHost) {
+        throw new Error("VITE_API_URL is not set in the server environment (SSR loader: Required).");
+      }
+      const apiHost = rawApiHost.replace(/\/+$/, "");
+      const dapper = new DapperTs(() => ({ apiHost, sessionId: undefined }));

14-19: Prefer a shared createServerDapper() helper to cut repetition

If you accept the helper approach, this block reduces to a single call.

apps/cyberstorm-remix/app/p/tabs/Wiki/Wiki.tsx (2)

14-19: SSR env fetch looks good; add a defensive check and URL normalization

Ensures clearer failure modes and consistent request base.

-    const dapper = new DapperTs(() => {
-      return {
-        apiHost: process.env.VITE_API_URL,
-        sessionId: undefined,
-      };
-    });
+    const rawApiHost = process.env.VITE_API_URL ?? "";
+    if (!rawApiHost) {
+      throw new Error("VITE_API_URL is not set in the server environment (SSR loader: Wiki).");
+    }
+    const apiHost = rawApiHost.replace(/\/+$/, "");
+    const dapper = new DapperTs(() => ({ apiHost, sessionId: undefined }));

14-19: Consider centralizing the DapperTs construction

Adopt a createServerDapper() helper for consistency with other loaders.

apps/cyberstorm-remix/app/c/community.tsx (2)

65-69: Validate and normalize VITE_API_URL before passing to DapperTs

Protect against undefined env and stray slashes.

-    const dapper = new DapperTs(() => {
-      return {
-        apiHost: process.env.VITE_API_URL,
-        sessionId: undefined,
-      };
-    });
+    const rawApiHost = process.env.VITE_API_URL ?? "";
+    if (!rawApiHost) {
+      throw new Error("VITE_API_URL is not set in the server environment (SSR loader: Community).");
+    }
+    const apiHost = rawApiHost.replace(/\/+$/, "");
+    const dapper = new DapperTs(() => ({ apiHost, sessionId: undefined }));

31-33: Align OG URL domain resolution with SSR approach

Meta uses import.meta.env.VITE_SITE_URL. If your goal is to consolidate SSR/CSR domain sourcing, consider switching this to the same SSR-aware mechanism you introduced elsewhere (e.g., process.env or a resolved domain from request/context) to avoid mismatches across environments.

apps/cyberstorm-remix/app/p/packageEdit.tsx (2)

45-50: Same SSR guard/normalization for VITE_API_URL

Keep error handling consistent and avoid accidental double slashes in requests.

-      const dapper = new DapperTs(() => {
-        return {
-          apiHost: process.env.VITE_API_URL,
-          sessionId: undefined,
-        };
-      });
+      const rawApiHost = process.env.VITE_API_URL ?? "";
+      if (!rawApiHost) {
+        throw new Error("VITE_API_URL is not set in the server environment (SSR loader: packageEdit).");
+      }
+      const apiHost = rawApiHost.replace(/\/+$/, "");
+      const dapper = new DapperTs(() => ({ apiHost, sessionId: undefined }));

45-50: Optional: factor via createServerDapper()

Adopt the shared helper to avoid repeating env checks and normalization throughout the codebase.

apps/cyberstorm-remix/app/p/tabs/Versions/Versions.tsx (1)

49-53: Avoid throwing during error path: versionsSchema.parse({}) may itself throw

If versionsSchema doesn’t accept {}, this will throw inside the error branch and surface as a 500. Prefer a safe default or safeParse.

-          versions: versionsSchema.parse({}),
+          versions: (versionsSchema.safeParse({}).success
+            ? versionsSchema.parse({})
+            : []),

If the schema shape is known, return that explicit empty shape instead of {}. Happy to adjust to the correct default if you share the schema.

Also applies to: 60-63

apps/cyberstorm-remix/app/p/team/Team.tsx (1)

41-43: Avoid mutating API data when sorting sections

filters.sections.sort(...) mutates the array returned by the API. Prefer copying before sorting to prevent accidental side effects if filters is reused.

-      const sortedSections = filters.sections.sort(
+      const sortedSections = [...filters.sections].sort(
         (a, b) => b.priority - a.priority
       );
apps/cyberstorm-remix/app/p/tabs/Changelog/Changelog.tsx (1)

88-91: Confirm HTML sanitization before dangerouslySetInnerHTML

If the API doesn’t sanitize changelog.html, this is an XSS vector. If it is sanitized upstream, consider annotating that contract here to make the trust boundary explicit.

I can wire in a client-side sanitizer (e.g., DOMPurify) if upstream guarantees are weak or vary across environments.

apps/cyberstorm-remix/app/p/tabs/Wiki/WikiPage.tsx (1)

27-33: Consider consistent 404 semantics for missing pages

Throwing new Error("Page not found") results in a 500 by default. Use a Response with 404 for consistency with other routes.

-    if (!pageId) {
-      throw new Error("Page not found");
-    }
+    if (!pageId) {
+      throw new Response("Page not found", { status: 404 });
+    }
apps/cyberstorm-remix/cyberstorm/utils/ThunderstoreAuth.tsx (3)

7-15: Unify SSR/CSR env resolution and add safe fallbacks (avoid undefined).

CSR branch lacks a default; if VITE_SITE_URL or VITE_AUTH_RETURN_URL is missing at build time, domain/returnDomain can become undefined, producing broken URLs at runtime. Also prefer nullish coalescing over logical OR to avoid accidentally treating an intentional empty string as falsy.

Apply this diff to make both branches consistent, add a sensible fallback for returnDomain, and normalize trailing slashes:

-  let domain: string;
-  let returnDomain: string;
-  if (import.meta.env.SSR) {
-    domain = process.env.VITE_SITE_URL || "";
-    returnDomain = process.env.VITE_AUTH_RETURN_URL || "";
-  } else {
-    domain = import.meta.env.VITE_SITE_URL;
-    returnDomain = import.meta.env.VITE_AUTH_RETURN_URL;
-  }
+  // SSR-aware env lookup with safe defaults and normalization
+  let domain =
+    import.meta.env.SSR
+      ? (process.env.VITE_SITE_URL ?? "")
+      : (import.meta.env.VITE_SITE_URL ?? "");
+  let returnDomain =
+    import.meta.env.SSR
+      ? (process.env.VITE_AUTH_RETURN_URL ?? domain)
+      : (import.meta.env.VITE_AUTH_RETURN_URL ?? domain);
+  // Trim trailing slashes to avoid // in constructed URLs
+  domain = domain.replace(/\/+$/, "");
+  returnDomain = returnDomain.replace(/\/+$/, "");

17-21: Build the login URL robustly; handle missing envs and avoid “//” artifacts.

String concat works but is brittle for slashes and defaults. With the normalization above, keep it simple and ensure next defaults correctly when not provided.

Apply this diff:

-  return `${domain}/auth/login/${props.type}/${
-    props.nextUrl
-      ? `?next=${encodeURIComponent(props.nextUrl)}`
-      : `?next=${encodeURIComponent(`${returnDomain}/communities/`)}`
-  }`;
+  const next = props.nextUrl ?? `${returnDomain}/communities/`;
+  return `${domain}/auth/login/${props.type}/?next=${encodeURIComponent(next)}`;

Please verify in both SSR and CSR:

  • When envs are set, resulting URL is absolute and correct.
  • When VITE_AUTH_RETURN_URL is missing, next falls back to ${VITE_SITE_URL}/communities/.
  • No double slashes appear around path boundaries.

6-22: Consider centralizing SSR-aware env access.

This SSR/CSR split will likely be needed elsewhere. A small utility (e.g., getPublicEnv("VITE_SITE_URL")) would reduce duplication and mistakes.

Example utility (outside this file):

// utils/env.ts
export function getPublicEnv(key: "VITE_SITE_URL" | "VITE_AUTH_RETURN_URL", fallback = ""): string {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const clientEnv = (import.meta as any).env as Record<string, string | undefined>;
  return import.meta.env.SSR ? (process.env[key] ?? fallback) : (clientEnv[key] ?? fallback);
}

Then here:

let domain = getPublicEnv("VITE_SITE_URL");
let returnDomain = getPublicEnv("VITE_AUTH_RETURN_URL", domain);
domain = domain.replace(/\/+$/, "");
returnDomain = returnDomain.replace(/\/+$/, "");
apps/cyberstorm-remix/app/root.tsx (3)

111-116: Add CSR fallback and use nullish coalescing for consistent domain resolution.

Currently the CSR branch lacks a default; domain can be undefined at runtime if the env is absent. Use the same defaulting logic for both branches.

Apply this diff:

-  let domain: string;
-  if (import.meta.env.SSR) {
-    domain = process.env.VITE_SITE_URL || "";
-  } else {
-    domain = import.meta.env.VITE_SITE_URL;
-  }
+  const domain =
+    import.meta.env.SSR
+      ? (process.env.VITE_SITE_URL ?? "")
+      : (import.meta.env.VITE_SITE_URL ?? "");

205-210: Repeat the same domain fallback fix in App().

Mirror the Layout logic to avoid divergence and potential undefined.

Apply this diff:

-  let domain: string;
-  if (import.meta.env.SSR) {
-    domain = process.env.VITE_SITE_URL || "";
-  } else {
-    domain = import.meta.env.VITE_SITE_URL;
-  }
+  const domain =
+    import.meta.env.SSR
+      ? (process.env.VITE_SITE_URL ?? "")
+      : (import.meta.env.VITE_SITE_URL ?? "");

108-116: DRY: Factor SSR-aware env resolution into a small helper.

Both Layout and App duplicate the same logic. A shared util (e.g., utils/env.ts:getPublicEnv) will reduce future inconsistencies.

See the example helper suggested in ThunderstoreAuth.tsx and import it here to compute domain once.

Also applies to: 205-210

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 70fe32c and fe5105d.

📒 Files selected for processing (17)
  • apps/cyberstorm-remix/app/c/community.tsx (1 hunks)
  • apps/cyberstorm-remix/app/communities/communities.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/dependants/Dependants.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/packageEdit.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/packageListing.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/tabs/Changelog/Changelog.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/tabs/Readme/Readme.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/tabs/Required/Required.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/tabs/Versions/Versions.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/tabs/Wiki/Wiki.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/tabs/Wiki/WikiFirstPage.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/tabs/Wiki/WikiPage.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/tabs/Wiki/WikiPageEdit.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/team/Team.tsx (1 hunks)
  • apps/cyberstorm-remix/app/root.tsx (2 hunks)
  • apps/cyberstorm-remix/app/upload/upload.tsx (1 hunks)
  • apps/cyberstorm-remix/cyberstorm/utils/ThunderstoreAuth.tsx (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/cyberstorm-remix/app/communities/communities.tsx (1)
.yarn/releases/yarn-1.19.0.cjs (1)
  • process (95664-95664)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Generate visual diffs
  • GitHub Check: CodeQL
  • GitHub Check: Run pre-commit

Comment on lines 134 to 138
return {
apiHost: import.meta.env.VITE_API_URL,
apiHost: process.env.VITE_API_URL,
sessionId: undefined,
};
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

SSR env switch is correct; add a fail-fast guard for missing VITE_API_URL

Good move to process.env for SSR. If VITE_API_URL is unset in the server env, DapperTs calls will fail later with harder-to-debug errors. Fail fast with a clear 500.

Apply this diff:

       const dapper = new DapperTs(() => {
-        return {
-          apiHost: process.env.VITE_API_URL,
-          sessionId: undefined,
-        };
+        const apiHost = process.env.VITE_API_URL;
+        if (!apiHost) {
+          // Avoid obscure downstream failures when env is misconfigured
+          throw new Response("Server misconfiguration: VITE_API_URL is not set", { status: 500 });
+        }
+        return {
+          apiHost,
+          sessionId: undefined,
+        };
       });

Verification helper to catch any remaining SSR usages of import.meta.env and spot loaders missing the guard:


🏁 Script executed:

#!/bin/bash
# 1) Find SSR-ish contexts (loaders, server utils) that still reference import.meta.env
rg -n -C2 'import\.meta\.env\.' apps/cyberstorm-remix/app

# 2) Review all DapperTs server initializations and ensure a guard exists
rg -n -C2 '(new DapperTs\(|DapperTs\()\s*=>\s*\{' apps/cyberstorm-remix/app | rg -n -C1 'apiHost: '

Length of output: 4801


🏁 Script executed:

#!/bin/bash
# List all DapperTs initializations across the codebase
rg -n -C3 'new DapperTs' apps/cyberstorm-remix/app || true

# Also find any direct DapperTs calls without 'new'
rg -n -C3 '\bDapperTs\(' apps/cyberstorm-remix/app || true

Length of output: 47761


Add fail-fast guard for missing VITE_API_URL across all SSR loaders

When apiHost is sourced directly from process.env.VITE_API_URL, a missing env var will only surface as obscure downstream errors. Failing fast with a clear 500 prevents hard-to-debug issues.

Apply this diff (or extract into a shared getServerConfig() helper) at each loader/DapperTs initialization that currently uses process.env.VITE_API_URL:

- const dapper = new DapperTs(() => ({
-   apiHost: process.env.VITE_API_URL,
-   sessionId: undefined,
- }));
+ const dapper = new DapperTs(() => {
+   const apiHost = process.env.VITE_API_URL;
+   if (!apiHost) {
+     throw new Response(
+       "Server misconfiguration: VITE_API_URL is not set",
+       { status: 500 }
+     );
+   }
+   return {
+     apiHost,
+     sessionId: undefined,
+   };
+ });

Locations requiring this update:

  • apps/cyberstorm-remix/app/upload/upload.tsx (loader)
  • apps/cyberstorm-remix/app/p/packageListing.tsx (loader)
  • apps/cyberstorm-remix/app/p/packageEdit.tsx (loader)
  • apps/cyberstorm-remix/app/p/dependants/Dependants.tsx (loader)
  • apps/cyberstorm-remix/app/p/tabs/Wiki/WikiPage.tsx (loader)
  • apps/cyberstorm-remix/app/p/tabs/Wiki/WikiFirstPage.tsx (loader)
  • apps/cyberstorm-remix/app/p/tabs/Wiki/Wiki.tsx (loader)
  • apps/cyberstorm-remix/app/p/tabs/Required/Required.tsx (loader)
  • apps/cyberstorm-remix/app/p/tabs/Versions/Versions.tsx (loader)
  • apps/cyberstorm-remix/app/communities/communities.tsx (loader)
  • apps/cyberstorm-remix/app/c/community.tsx (loader)
  • apps/cyberstorm-remix/app/p/team/Team.tsx (loader)
  • apps/cyberstorm-remix/app/p/tabs/Readme/Readme.tsx (loader)
  • apps/cyberstorm-remix/app/p/tabs/Changelog/Changelog.tsx (loader)

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/cyberstorm-remix/app/p/packageListing.tsx around lines 134-138, the
loader returns apiHost directly from process.env.VITE_API_URL which will cause
obscure downstream errors if unset; add a fail-fast guard that checks
process.env.VITE_API_URL and throws a 500 Response (or otherwise return a server
error) with a clear message like "Missing VITE_API_URL" when it's missing, and
replace direct env access with a small shared getServerConfig() helper (used by
all listed loaders) that validates the env, returns { apiHost, sessionId } when
present, and throws the 500 Response when not.

Comment on lines 10 to 15
const dapper = new DapperTs(() => {
return {
apiHost: import.meta.env.VITE_API_URL,
apiHost: process.env.VITE_API_URL,
sessionId: undefined,
};
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Validate presence of VITE_API_URL in SSR

Ensure the server env is configured; otherwise return a 500 with a clear message.

-      const dapper = new DapperTs(() => {
-        return {
-          apiHost: process.env.VITE_API_URL,
-          sessionId: undefined,
-        };
-      });
+      const apiHost = process.env.VITE_API_URL;
+      if (!apiHost) {
+        throw new Response("API host is not configured (VITE_API_URL missing)", { status: 500 });
+      }
+      const dapper = new DapperTs(() => ({
+        apiHost,
+        sessionId: undefined,
+      }));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const dapper = new DapperTs(() => {
return {
apiHost: import.meta.env.VITE_API_URL,
apiHost: process.env.VITE_API_URL,
sessionId: undefined,
};
});
const apiHost = process.env.VITE_API_URL;
if (!apiHost) {
throw new Response("API host is not configured (VITE_API_URL missing)", { status: 500 });
}
const dapper = new DapperTs(() => ({
apiHost,
sessionId: undefined,
}));
🤖 Prompt for AI Agents
In apps/cyberstorm-remix/app/p/tabs/Changelog/Changelog.tsx around lines 10-15,
ensure the server-side environment variable VITE_API_URL is present before
constructing DapperTs; if running in SSR (typeof window === 'undefined') and
process.env.VITE_API_URL is missing, immediately return/throw a 500 Response
with a clear message like "VITE_API_URL not configured" (or use Remix's
json/Response helpers), otherwise pass the validated apiHost into DapperTs; this
prevents creating the client with an undefined host and yields a proper 500
error when the server is misconfigured.

Comment on lines 10 to 15
const dapper = new DapperTs(() => {
return {
apiHost: import.meta.env.VITE_API_URL,
apiHost: process.env.VITE_API_URL,
sessionId: undefined,
};
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Harden env var usage: validate and normalize VITE_API_URL before passing to DapperTs

process.env values are string | undefined. If VITE_API_URL is missing, DapperTs will receive undefined and fail later. Fail fast with a clear error and normalize trailing slashes to avoid accidental double slashes in requests.

Apply this diff:

-      const dapper = new DapperTs(() => {
-        return {
-          apiHost: process.env.VITE_API_URL,
-          sessionId: undefined,
-        };
-      });
+      const rawApiHost = process.env.VITE_API_URL ?? "";
+      if (!rawApiHost) {
+        throw new Error("VITE_API_URL is not set in the server environment (SSR loader: Readme).");
+      }
+      const apiHost = rawApiHost.replace(/\/+$/, "");
+      const dapper = new DapperTs(() => ({
+        apiHost,
+        sessionId: undefined,
+      }));

Optional repo-wide verification to ensure no server loader still relies on import.meta.env for apiHost:


🏁 Script executed:

#!/bin/bash
# Verify all server loaders use process.env for DapperTs apiHost
rg -nP --type=ts --type=tsx -C2 'new\s+DapperTs\s*\(\s*\(\)\s*=>\s*{\s*return\s*{\s*[^}]*apiHost:' apps/cyberstorm-remix | sed 's/^/HIT: /'
echo "---- Leftovers using import.meta.env.VITE_API_URL ----"
rg -n 'import\.meta\.env\.VITE_API_URL' apps/cyberstorm-remix || true

Length of output: 669


Ensure all DapperTs apiHost usages validate and normalize VITE_API_URL

Your app still has a few places where import.meta.env.VITE_API_URL is used directly. Those need the same “fail-fast” validation and trailing-slash normalization you applied in the SSR loader. Specifically:

• In apps/cyberstorm-remix/app/middlewares.ts
– Line 12: getSessionContext(import.meta.env.VITE_API_URL)
– Line 17: const session = getSessionContext(import.meta.env.VITE_API_URL);

• In apps/cyberstorm-remix/app/entry.client.tsx
– Line 12 (commented example):
ts // apiHost: import.meta.env.VITE_API_URL ?? "MISSING_API_HOST",

Please refactor these to mirror the pattern in Readme.tsx:

- import.meta.env.VITE_API_URL
+ (() => {
+   const rawApiHost = process.env.VITE_API_URL ?? "";
+   if (!rawApiHost) {
+     throw new Error(
+       "VITE_API_URL must be set in the environment (middleware/session loader)."
+     );
+   }
+   return rawApiHost.replace(/\/+$/, "");
+ })()

For example, in middlewares.ts:

- const session = getSessionContext(import.meta.env.VITE_API_URL);
+ const rawApiHost = process.env.VITE_API_URL ?? "";
+ if (!rawApiHost) {
+   throw new Error(
+     "VITE_API_URL is required for session context (middlewares.ts)."
+   );
+ }
+ const apiHost = rawApiHost.replace(/\/+$/, "");
+ const session = getSessionContext(apiHost);

And update the client entry snippet similarly to ensure consistency across all loaders and entrypoints.

🤖 Prompt for AI Agents
In apps/cyberstorm-remix/app/p/tabs/Readme/Readme.tsx around lines 10 to 15, and
related usages in apps/cyberstorm-remix/app/middlewares.ts (lines ~12 and ~17)
and apps/cyberstorm-remix/app/entry.client.tsx (line ~12 commented snippet), the
code uses import.meta.env.VITE_API_URL directly; replicate the Readme.tsx
pattern by centralizing validation/normalization of VITE_API_URL
(throwing/console.error if missing), ensure the returned apiHost has a trailing
slash normalized, and pass that normalized value into DapperTs/getSessionContext
and into the client entry snippet so all entrypoints fail-fast and use the same
normalized host string.

Comment on lines 33 to 38
const dapper = new DapperTs(() => {
return {
apiHost: import.meta.env.VITE_API_URL,
apiHost: process.env.VITE_API_URL,
sessionId: undefined,
};
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Guard against missing VITE_API_URL in SSR loader

process.env.VITE_API_URL can be undefined at runtime, causing DapperTs to be configured with an invalid host. Add an explicit invariant with a clear 500 to avoid confusing downstream failures.

-      const dapper = new DapperTs(() => {
-        return {
-          apiHost: process.env.VITE_API_URL,
-          sessionId: undefined,
-        };
-      });
+      const apiHost = process.env.VITE_API_URL;
+      if (!apiHost) {
+        throw new Response("API host is not configured (VITE_API_URL missing)", { status: 500 });
+      }
+      const dapper = new DapperTs(() => ({
+        apiHost,
+        sessionId: undefined,
+      }));

To scan the repo for other unguarded usages and review them quickly, run:


🏁 Script executed:

#!/bin/bash
# Find all SSR loaders using process.env.VITE_API_URL without a guard nearby
rg -n --type=ts --type=tsx 'process\.env\.VITE_API_URL' -C2

Length of output: 89


🏁 Script executed:

#!/bin/bash
# Find all occurrences of VITE_API_URL in TS/TSX files with context
rg -n 'process\.env\.VITE_API_URL' -g '*.ts' -g '*.tsx' -C2

Length of output: 6218


Guard against missing VITE_API_URL in all SSR loaders

We found 15 unguarded initializations of DapperTs using process.env.VITE_API_URL. If the env var is undefined at runtime, downstream calls will fail in confusing, non-HTTP-friendly ways. Please centralize and enforce a guard so any missing configuration immediately surfaces as a 500 response.

• Files (unguarded apiHost: process.env.VITE_API_URL at these lines):

  • apps/cyberstorm-remix/app/c/community.tsx:66
  • apps/cyberstorm-remix/app/communities/communities.tsx:71
  • apps/cyberstorm-remix/app/p/dependants/Dependants.tsx:30
  • apps/cyberstorm-remix/app/p/tabs/Wiki/Wiki.tsx:16
  • apps/cyberstorm-remix/app/p/tabs/Wiki/WikiPage.tsx:18
  • apps/cyberstorm-remix/app/p/tabs/Wiki/WikiPageEdit.tsx:43
  • apps/cyberstorm-remix/app/p/tabs/Versions/Versions.tsx:35
  • apps/cyberstorm-remix/app/p/tabs/Required/Required.tsx:16
  • apps/cyberstorm-remix/app/p/tabs/Wiki/WikiFirstPage.tsx:13
  • apps/cyberstorm-remix/app/p/tabs/Changelog/Changelog.tsx:12
  • apps/cyberstorm-remix/app/p/tabs/Readme/Readme.tsx:12
  • apps/cyberstorm-remix/app/upload/upload.tsx:73
  • apps/cyberstorm-remix/app/p/packageEdit.tsx:47
  • apps/cyberstorm-remix/app/p/team/Team.tsx:25
  • apps/cyberstorm-remix/app/p/packageListing.tsx:135

Suggested essential refactor

  1. Create a shared helper (e.g. app/utils/getApiHost.ts):
export function getApiHost(): string {
  const host = process.env.VITE_API_URL;
  if (!host) {
    throw new Response(
      "API host is not configured (VITE_API_URL missing)",
      { status: 500 }
    );
  }
  return host;
}
  1. Update each loader:
-import { DapperTs } from "dapper-ts";
-const dapper = new DapperTs(() => ({
-  apiHost: process.env.VITE_API_URL,
-  sessionId: undefined,
-}));
+import { DapperTs } from "dapper-ts";
+import { getApiHost } from "~/utils/getApiHost";
+const dapper = new DapperTs(() => ({
+  apiHost: getApiHost(),
+  sessionId: undefined,
+}));

This ensures every SSR loader fails fast with a clear 500 if the API URL isn’t set.

🤖 Prompt for AI Agents
In apps/cyberstorm-remix/app/p/tabs/Versions/Versions.tsx around lines 33 to 38,
the DapperTs initialization uses process.env.VITE_API_URL directly which can be
undefined at runtime; create a shared helper (e.g. app/utils/getApiHost.ts) that
reads process.env.VITE_API_URL and throws a Response with status 500 if missing,
then replace direct uses of process.env.VITE_API_URL in this file (and the other
listed SSR loader files) by calling getApiHost() and passing its returned string
into new DapperTs so missing configuration fails fast with a clear 500 response.

Comment on lines 11 to 16
const dapper = new DapperTs(() => {
return {
apiHost: import.meta.env.VITE_API_URL,
apiHost: process.env.VITE_API_URL,
sessionId: undefined,
};
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add an SSR env invariant for VITE_API_URL

Keep the pattern consistent and fail fast if the host is not configured.

-    const dapper = new DapperTs(() => {
-      return {
-        apiHost: process.env.VITE_API_URL,
-        sessionId: undefined,
-      };
-    });
+    const apiHost = process.env.VITE_API_URL;
+    if (!apiHost) {
+      throw new Response("API host is not configured (VITE_API_URL missing)", { status: 500 });
+    }
+    const dapper = new DapperTs(() => ({
+      apiHost,
+      sessionId: undefined,
+    }));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const dapper = new DapperTs(() => {
return {
apiHost: import.meta.env.VITE_API_URL,
apiHost: process.env.VITE_API_URL,
sessionId: undefined,
};
});
const apiHost = process.env.VITE_API_URL;
if (!apiHost) {
throw new Response("API host is not configured (VITE_API_URL missing)", { status: 500 });
}
const dapper = new DapperTs(() => ({
apiHost,
sessionId: undefined,
}));
🤖 Prompt for AI Agents
In apps/cyberstorm-remix/app/p/tabs/Wiki/WikiFirstPage.tsx around lines 11-16,
add a server-side invariant check that process.env.VITE_API_URL is present
before constructing DapperTs and fail fast if missing; implement by reading
process.env.VITE_API_URL into a const at module/runtime start, throw a clear
Error (or use the project's invariant helper) when it's undefined/empty, then
pass that const into the DapperTs config instead of accessing process.env
directly.

Comment on lines 16 to 21
const dapper = new DapperTs(() => {
return {
apiHost: import.meta.env.VITE_API_URL,
apiHost: process.env.VITE_API_URL,
sessionId: undefined,
};
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

SSR env guard for VITE_API_URL

Same as other loaders; add a clear failure mode when env is missing.

-    const dapper = new DapperTs(() => {
-      return {
-        apiHost: process.env.VITE_API_URL,
-        sessionId: undefined,
-      };
-    });
+    const apiHost = process.env.VITE_API_URL;
+    if (!apiHost) {
+      throw new Response("API host is not configured (VITE_API_URL missing)", { status: 500 });
+    }
+    const dapper = new DapperTs(() => ({
+      apiHost,
+      sessionId: undefined,
+    }));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const dapper = new DapperTs(() => {
return {
apiHost: import.meta.env.VITE_API_URL,
apiHost: process.env.VITE_API_URL,
sessionId: undefined,
};
});
const apiHost = process.env.VITE_API_URL;
if (!apiHost) {
throw new Response(
"API host is not configured (VITE_API_URL missing)",
{ status: 500 }
);
}
const dapper = new DapperTs(() => ({
apiHost,
sessionId: undefined,
}));
🤖 Prompt for AI Agents
In apps/cyberstorm-remix/app/p/tabs/Wiki/WikiPage.tsx around lines 16 to 21, the
DapperTs initializer reads process.env.VITE_API_URL without guarding for
SSR/missing env; add an explicit runtime check that throws a clear error (or
uses an invariant) if VITE_API_URL is undefined/empty, and then pass the
validated URL into apiHost so the app fails fast with a helpful message on SSR
when the env is not provided.

Comment on lines 23 to 28
const dapper = new DapperTs(() => {
return {
apiHost: import.meta.env.VITE_API_URL,
apiHost: process.env.VITE_API_URL,
sessionId: undefined,
};
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

❓ Verification inconclusive

SSR env may be undefined — validate VITE_API_URL before constructing DapperTs

Same reasoning as other loaders; fail fast with a clear error if env is missing.

-      const dapper = new DapperTs(() => {
-        return {
-          apiHost: process.env.VITE_API_URL,
-          sessionId: undefined,
-        };
-      });
+      const apiHost = process.env.VITE_API_URL;
+      if (!apiHost) {
+        throw new Response("API host is not configured (VITE_API_URL missing)", { status: 500 });
+      }
+      const dapper = new DapperTs(() => ({
+        apiHost,
+        sessionId: undefined,
+      }));

Validate VITE_API_URL at runtime before instantiating DapperTs

VITE-prefixed env variables are only exposed as strings via import.meta.env and will be undefined if not set (vitejs.dev). Remix’s built-in dotenv support only applies in remix dev—it does not load .env in production, so process.env.VITE_API_URL can also be undefined at runtime unless your deployment explicitly supplies it (remix.run).

• File: apps/cyberstorm-remix/app/p/team/Team.tsx
Lines: ~23–28

Please update this block to extract and validate the API host, failing fast with a clear 500 error if it’s missing:

-      const dapper = new DapperTs(() => {
-        return {
-          apiHost: process.env.VITE_API_URL,
-          sessionId: undefined,
-        };
-      });
+      const apiHost = process.env.VITE_API_URL;
+      if (!apiHost) {
+        throw new Response(
+          "API host is not configured (VITE_API_URL missing)",
+          { status: 500 }
+        );
+      }
+      const dapper = new DapperTs(() => ({
+        apiHost,
+        sessionId: undefined,
+      }));
🤖 Prompt for AI Agents
In apps/cyberstorm-remix/app/p/team/Team.tsx around lines 23–28, don't read
process.env directly into DapperTs; first extract the API host from
import.meta.env.VITE_API_URL (with an optional fallback to
process.env.VITE_API_URL), validate it is a non-empty string, and only then
instantiate DapperTs. If the value is missing or empty, fail fast by throwing a
clear 500 Response (e.g. throw new Response('VITE_API_URL is not set', { status:
500 })) so the app surfaces a clear error rather than silently passing undefined
into DapperTs.

Apparently the Vite env variables are not available in loaders or SSR in
general. So we have to use the process instead on server side code.
@Oksamies Oksamies force-pushed the 08-26-fix_env_variable_grabbing branch from fe5105d to 36228a4 Compare August 26, 2025 12:22
@Oksamies Oksamies merged commit eb54bac into master Aug 26, 2025
25 of 28 checks passed
@Oksamies Oksamies deleted the 08-26-fix_env_variable_grabbing branch August 26, 2025 12:28
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
apps/cyberstorm-remix/app/p/tabs/Versions/Versions.tsx (1)

33-38: Fail fast if VITE_API_URL is missing in SSR loader

Directly passing process.env.VITE_API_URL can be undefined at runtime, causing opaque downstream failures. Add an explicit guard or use the shared helper (see prior review).

Minimal local fix:

-      const dapper = new DapperTs(() => {
-        return {
-          apiHost: process.env.VITE_API_URL,
-          sessionId: undefined,
-        };
-      });
+      const apiHost = process.env.VITE_API_URL;
+      if (!apiHost) {
+        throw new Response("API host is not configured (VITE_API_URL missing)", { status: 500 });
+      }
+      const dapper = new DapperTs(() => ({
+        apiHost,
+        sessionId: undefined,
+      }));

If you prefer a centralized approach, introduce a getApiHost() helper and reuse it across loaders (as suggested previously).

🧹 Nitpick comments (2)
.github/workflows/test.yml (1)

96-99: Ensure repo/org variables exist and are correct after renaming to VITE_ keys*

These reference the vars context. If the corresponding NEXT_PUBLIC_* repo or org variables are absent or misconfigured, builds may break silently or at runtime. Consider adding an early validation step to fail fast with a clear message.

Example validation step (add after "checkout"):

      - name: Validate required env vars
        run: |
          required=(VITE_SITE_URL VITE_API_URL VITE_AUTH_BASE_URL VITE_AUTH_RETURN_URL)
          for k in "${required[@]}"; do
            if [ -z "${!k}" ]; then
              echo "::error::Missing required env var: $k"
              exit 1
            fi
          done

Optional: mirror these in the Chromatic job if Storybook needs non-default domains for links; otherwise the defaults in code will be used.

apps/cyberstorm-storybook/constants.ts (1)

1-4: Normalize domains to avoid trailing-slash issues in URL composition

Looks good. To guard against accidental trailing slashes in env values (which can produce double slashes in URLs), normalize once at import.

-export const API_DOMAIN = process.env.VITE_API_URL || "https://thunderstore.io";
+const stripTrailingSlash = (s: string) => s.replace(/\/+$/, "");
+export const API_DOMAIN = stripTrailingSlash(process.env.VITE_API_URL || "https://thunderstore.io");

 export const ROOT_DOMAIN =
-  process.env.VITE_SITE_URL || "https://thunderstore.io";
+  stripTrailingSlash(process.env.VITE_SITE_URL || "https://thunderstore.io");
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between fe5105d and 36228a4.

📒 Files selected for processing (20)
  • .github/workflows/test.yml (1 hunks)
  • apps/cyberstorm-remix/app/c/community.tsx (1 hunks)
  • apps/cyberstorm-remix/app/communities/communities.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/dependants/Dependants.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/packageEdit.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/packageListing.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/tabs/Changelog/Changelog.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/tabs/Readme/Readme.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/tabs/Required/Required.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/tabs/Versions/Versions.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/tabs/Wiki/Wiki.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/tabs/Wiki/WikiFirstPage.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/tabs/Wiki/WikiPage.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/tabs/Wiki/WikiPageEdit.tsx (1 hunks)
  • apps/cyberstorm-remix/app/p/team/Team.tsx (1 hunks)
  • apps/cyberstorm-remix/app/root.tsx (2 hunks)
  • apps/cyberstorm-remix/app/upload/upload.tsx (1 hunks)
  • apps/cyberstorm-remix/cyberstorm/utils/ThunderstoreAuth.tsx (1 hunks)
  • apps/cyberstorm-storybook/constants.ts (1 hunks)
  • tools/visual-diff-ci/run_ci_script.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (16)
  • apps/cyberstorm-remix/app/p/tabs/Wiki/WikiFirstPage.tsx
  • apps/cyberstorm-remix/app/c/community.tsx
  • apps/cyberstorm-remix/app/p/tabs/Readme/Readme.tsx
  • apps/cyberstorm-remix/app/upload/upload.tsx
  • apps/cyberstorm-remix/app/p/tabs/Changelog/Changelog.tsx
  • apps/cyberstorm-remix/app/p/packageListing.tsx
  • apps/cyberstorm-remix/app/p/tabs/Wiki/WikiPage.tsx
  • apps/cyberstorm-remix/app/p/team/Team.tsx
  • apps/cyberstorm-remix/app/root.tsx
  • apps/cyberstorm-remix/app/communities/communities.tsx
  • apps/cyberstorm-remix/app/p/tabs/Wiki/Wiki.tsx
  • apps/cyberstorm-remix/app/p/dependants/Dependants.tsx
  • apps/cyberstorm-remix/app/p/tabs/Wiki/WikiPageEdit.tsx
  • apps/cyberstorm-remix/app/p/packageEdit.tsx
  • apps/cyberstorm-remix/app/p/tabs/Required/Required.tsx
  • apps/cyberstorm-remix/cyberstorm/utils/ThunderstoreAuth.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Get Node version
  • GitHub Check: Generate visual diffs
  • GitHub Check: CodeQL

Comment on lines +140 to 144
"VITE_SITE_URL": "http://127.0.0.1:8000",
"VITE_API_URL": "http://127.0.0.1:8000",
"VITE_AUTH_BASE_URL": "http://127.0.0.1:8000",
"VITE_AUTH_RETURN_URL": "http://127.0.0.1:8000",
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify SITE/RETURN URL ports (likely 3000) vs API/AUTH_BASE (8000) to avoid redirect/domain mismatches

The dev server is started on port 3000 (Line 146), but VITE_SITE_URL and VITE_AUTH_RETURN_URL are set to 8000. If auth flows construct return URLs using these, the browser may be redirected to 8000 instead of the frontend (3000). Consider mapping:

  • VITE_API_URL, VITE_AUTH_BASE_URL → 8000 (backend)
  • VITE_SITE_URL, VITE_AUTH_RETURN_URL → 3000 (frontend)

Apply if appropriate:

-        "VITE_SITE_URL": "http://127.0.0.1:8000",
-        "VITE_API_URL": "http://127.0.0.1:8000",
-        "VITE_AUTH_BASE_URL": "http://127.0.0.1:8000",
-        "VITE_AUTH_RETURN_URL": "http://127.0.0.1:8000",
+        "VITE_SITE_URL": "http://127.0.0.1:3000",
+        "VITE_API_URL": "http://127.0.0.1:8000",
+        "VITE_AUTH_BASE_URL": "http://127.0.0.1:8000",
+        "VITE_AUTH_RETURN_URL": "http://127.0.0.1:3000",

To quickly confirm port usage and return URL construction hotspots:


🏁 Script executed:

#!/bin/bash
# Frontend dev server port
rg -nC2 'workspace", "@thunderstore/cyberstorm-remix", "start".*--port", "3000' tools/visual-diff-ci/run_ci_script.py

# Places building login/return URLs or using these envs
rg -n --type=ts --type=tsx 'VITE_(SITE_URL|AUTH_RETURN_URL|AUTH_BASE_URL|API_URL)'

Length of output: 443


🏁 Script executed:

#!/bin/bash
# Confirm frontend dev server port usage
rg -nC2 '--port", "3000' tools/visual-diff-ci/run_ci_script.py

# Show the environment configuration block
rg -n 'configs\s*=\s*{' -C5 tools/visual-diff-ci/run_ci_script.py

Length of output: 643


Fix frontend URL ports to match the dev server

The CI script launches the frontend on port 3000 (BgProcess at line 146), but both VITE_SITE_URL and VITE_AUTH_RETURN_URL are still pointing to port 8000. This will cause auth redirects to hit the backend instead of your running frontend. Please update the env block in tools/visual-diff-ci/run_ci_script.py:

• File: tools/visual-diff-ci/run_ci_script.py
Lines: ~140–144

-        "VITE_SITE_URL": "http://127.0.0.1:8000",
-        "VITE_AUTH_RETURN_URL": "http://127.0.0.1:8000",
+        "VITE_SITE_URL":        "http://127.0.0.1:3000",
+        "VITE_AUTH_RETURN_URL": "http://127.0.0.1:3000",

Leave the API-related URLs on port 8000:

         "VITE_API_URL":        "http://127.0.0.1:8000",
         "VITE_AUTH_BASE_URL":  "http://127.0.0.1:8000",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"VITE_SITE_URL": "http://127.0.0.1:8000",
"VITE_API_URL": "http://127.0.0.1:8000",
"VITE_AUTH_BASE_URL": "http://127.0.0.1:8000",
"VITE_AUTH_RETURN_URL": "http://127.0.0.1:8000",
}
"VITE_SITE_URL": "http://127.0.0.1:3000",
"VITE_API_URL": "http://127.0.0.1:8000",
"VITE_AUTH_BASE_URL": "http://127.0.0.1:8000",
"VITE_AUTH_RETURN_URL": "http://127.0.0.1:3000",
}
🤖 Prompt for AI Agents
In tools/visual-diff-ci/run_ci_script.py around lines 140 to 144, the env dict
sets VITE_SITE_URL and VITE_AUTH_RETURN_URL to port 8000 while the frontend is
started on port 3000 (BgProcess at ~line 146); update VITE_SITE_URL and
VITE_AUTH_RETURN_URL to use http://127.0.0.1:3000 so auth redirects go to the
running frontend, and keep VITE_API_URL and VITE_AUTH_BASE_URL pointing at port
8000 unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant