SPB Git forge

spb/market-atlas

Public
12commits 1branches 0releases
1.1 MBsize
maindefault branch
10 days agolast push
TypeScript 96.7% SQL 1.6% CSS 0.8% JavaScript 0.5%
2.4 KB · 57 lines typescript
Raw Blame History
1import type { NextConfig } from "next";2import { existsSync } from "node:fs";3import path from "node:path";45// Monorepo: a single `.env` lives at the repository root; Next only reads the app directory.6for (const candidate of [path.resolve(process.cwd(), "../../.env"), path.resolve(process.cwd(), ".env")]) {7  if (existsSync(candidate)) {8    try {9      process.loadEnvFile(candidate);10    } catch {11      /* ignore malformed env */12    }13  }14}1516// Dev: API on :8391 (repo .env). Production: the API process is the public edge (:8380) and proxies non-/v1 paths here (:8382).17const API_URL = (process.env.API_URL ?? "http://127.0.0.1:8391").replace(/\/$/, "");18const isDevApi = /:8391$/.test(API_URL) || /localhost|127\.0\.0\.1/.test(API_URL) && process.env.NODE_ENV !== "production";1920const nextConfig: NextConfig = {21  distDir: process.env.NEXT_DIST_DIR || ".next",22  reactStrictMode: true,23  poweredByHeader: false,24  allowedDevOrigins: ["127.0.0.1", "localhost"],25  outputFileTracingRoot: path.resolve(__dirname, "../.."),26  experimental: { optimizePackageImports: ["lucide-react"] },27  env: {28    // In development the browser talks to the API directly for WebSocket (rewrites do not proxy upgrades).29    NEXT_PUBLIC_WS_URL: process.env.NEXT_PUBLIC_WS_URL ?? (isDevApi ? API_URL.replace(/^http/, "ws") + "/v1/stream" : ""),30    NEXT_PUBLIC_SITE_URL: process.env.NEXT_PUBLIC_SITE_URL ?? process.env.MA_SITE_URL ?? "https://www.market-atlas.co",31  },32  async rewrites() {33    return [{ source: "/v1/:path*", destination: `${API_URL}/v1/:path*` }];34  },35  async headers() {36    const PUBLIC_CACHE = { key: "Cache-Control", value: "public, s-maxage=60, stale-while-revalidate=600" };37    const NO_STORE = { key: "Cache-Control", value: "private, no-store" };38    return [39      {40        source: "/(.*)",41        headers: [42          { key: "X-Content-Type-Options", value: "nosniff" },43          { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },44          { key: "X-Frame-Options", value: "SAMEORIGIN" },45          { key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=()" },46        ],47      },48      { source: "/methodology", headers: [PUBLIC_CACHE] },49      { source: "/developers", headers: [PUBLIC_CACHE] },50      { source: "/licensing", headers: [PUBLIC_CACHE] },51      { source: "/admin/:path*", headers: [NO_STORE] },52    ];53  },54};5556export default nextConfig;57