diff --git a/apps/web/.gitignore b/apps/web/.gitignore index a27c2b8b2..04a379bf2 100644 --- a/apps/web/.gitignore +++ b/apps/web/.gitignore @@ -18,3 +18,4 @@ storybook-static .env.staging .env.dev .env.local +.vercel diff --git a/apps/web/package.json b/apps/web/package.json index a233af00c..432398160 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -10,6 +10,7 @@ "build:production": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode production -- --typecheck", "build:local": "pnpm prebuild && cross-env NODE_OPTIONS=--max-old-space-size=12288 vite build -- --typecheck --local", "build-storybook": "storybook build", + "log:staging": "WRANGLER_LOG=debug npx wrangler tail --format=pretty --env=staging", "build:visualize": "npx vite-bundle-visualizer", "deploy:dev": "pnpm run build && npx wrangler deploy .output/server/index.mjs --env dev --assets .output/public", "deploy:production": "pnpm run build:production && npx wrangler deploy .output/server/index.mjs --env production --assets .output/public", diff --git a/apps/web/src/middleware/csp-helper.ts b/apps/web/src/middleware/csp-helper.ts index 50cc95240..54b41dc65 100644 --- a/apps/web/src/middleware/csp-helper.ts +++ b/apps/web/src/middleware/csp-helper.ts @@ -28,8 +28,8 @@ export const createCspHeader = (isEmbed = false): string => { return [ // Default directives "default-src 'self'", - // Scripts - "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net https://*.cloudflareinsights.com https://*.posthog.com https://us-assets.i.posthog.com https://eu-assets.i.posthog.com", + // Scripts - removed 'unsafe-eval' which can cause hydration issues in Cloudflare + "script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://*.cloudflareinsights.com https://*.posthog.com https://us-assets.i.posthog.com https://eu-assets.i.posthog.com", // Styles "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://cdn.jsdelivr.net", // Images diff --git a/apps/web/src/middleware/shared-headers.ts b/apps/web/src/middleware/shared-headers.ts index 6d1325ddc..fe2575f72 100644 --- a/apps/web/src/middleware/shared-headers.ts +++ b/apps/web/src/middleware/shared-headers.ts @@ -4,9 +4,8 @@ export const htmlCacheHeaders = [ { httpEquiv: 'Pragma', content: 'cache' }, ]; -// Only use aggressive no-cache for specific routes that need it +// Use less aggressive caching to work better with Cloudflare export const preventBrowserCacheHeaders = [ - { httpEquiv: 'Cache-Control', content: 'no-cache, no-store, must-revalidate' }, + { httpEquiv: 'Cache-Control', content: 'public, max-age=0, must-revalidate' }, { httpEquiv: 'Pragma', content: 'no-cache' }, - { httpEquiv: 'Expires', content: '0' }, ]; diff --git a/apps/web/src/routes/__root.tsx b/apps/web/src/routes/__root.tsx index 56617c206..c95460edd 100644 --- a/apps/web/src/routes/__root.tsx +++ b/apps/web/src/routes/__root.tsx @@ -1,6 +1,7 @@ import { createRootRouteWithContext, HeadContent, Scripts } from '@tanstack/react-router'; +import { ErrorBoundary } from 'react-error-boundary'; import { RootProviders } from '@/context/Providers'; -import { htmlCacheHeaders } from '@/middleware/shared-headers'; +import { preventBrowserCacheHeaders } from '@/middleware/shared-headers'; import shareImage from '../assets/png/default_preview.png'; import favicon from '../assets/png/favicon.ico'; import { TanstackDevtools } from '../integrations/tanstack-dev-tools/tanstack-devtools'; @@ -31,7 +32,7 @@ export const Route = createRootRouteWithContext()({ { name: 'og:type', content: 'website' }, { name: 'og:locale', content: 'en_US' }, { name: 'og:site_name', content: 'Buster' }, - ...htmlCacheHeaders, + ...preventBrowserCacheHeaders, ], links: [ { rel: 'stylesheet', href: appCss }, @@ -55,6 +56,7 @@ function RootDocument({ children }: { children: React.ReactNode }) { {children} + diff --git a/apps/web/src/routes/app.tsx b/apps/web/src/routes/app.tsx index 5800e0e78..cd4f4c745 100644 --- a/apps/web/src/routes/app.tsx +++ b/apps/web/src/routes/app.tsx @@ -14,6 +14,7 @@ const DEFAULT_LAYOUT: LayoutSize = ['230px', 'auto']; export const Route = createFileRoute('/app')({ head: () => { + console.log('app head'); return { meta: [...preventBrowserCacheHeaders], }; @@ -21,7 +22,10 @@ export const Route = createFileRoute('/app')({ context: ({ context }) => ({ ...context, getAppLayout }), beforeLoad: async () => { try { + console.log('app beforeLoad - getSupabaseSession'); const { isExpired, accessToken = '' } = await getSupabaseSession(); + console.log('app beforeLoad - getSupabaseSession - isExpired', isExpired); + console.log('app beforeLoad - getSupabaseSession - accessToken', accessToken); if (isExpired || !accessToken) { console.error('Access token is expired or not found'); @@ -39,6 +43,7 @@ export const Route = createFileRoute('/app')({ loader: async ({ context }) => { const { queryClient, accessToken } = context; try { + console.log('app loader - getAppLayout'); const [initialLayout, user] = await Promise.all([ getAppLayout({ id: PRIMARY_APP_LAYOUT_ID }), getSupabaseUser(), @@ -47,6 +52,8 @@ export const Route = createFileRoute('/app')({ prefetchListDatasources(queryClient), prefetchGetDatasets(queryClient), ]); + console.log('app loader - getAppLayout - initialLayout', initialLayout); + console.log('app loader - getAppLayout - user', user); if (!user) { console.error('User not found - redirecting to login'); @@ -66,7 +73,10 @@ export const Route = createFileRoute('/app')({ } }, component: () => { + console.log('app component'); const { user, accessToken } = Route.useLoaderData(); + console.log('app component - user', user); + console.log('app component - accessToken', accessToken); return ( diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts index 5bf7dd77b..dd1cb4631 100644 --- a/apps/web/vite.config.ts +++ b/apps/web/vite.config.ts @@ -11,7 +11,7 @@ const config = defineConfig(({ command, mode }) => { const isTypecheck = process.argv.includes('--typecheck') || process.env.TYPECHECK === 'true'; const useChecker = !process.env.VITEST && isBuild; const isLocalBuild = process.argv.includes('--local') || mode === 'development'; - const target = isLocalBuild ? ('bun' as const) : ('cloudflare-module' as const); + const target = isLocalBuild ? ('bun' as const) : ('vercel' as const); return { server: { port: 3000 },