From 4ee906e1ce964717b0a80d7a041829eb59cf8428 Mon Sep 17 00:00:00 2001 From: Rahul Jain Date: Wed, 15 Oct 2025 21:50:49 +0530 Subject: [PATCH] chore: load assets with assetPrefix --- next.config.ts | 186 +++++++++++++++++-------------- src/app/layout.tsx | 7 +- src/components/layout/footer.tsx | 3 +- src/components/layout/header.tsx | 3 +- src/lib/asset-path.ts | 14 +++ 5 files changed, 122 insertions(+), 91 deletions(-) create mode 100644 src/lib/asset-path.ts diff --git a/next.config.ts b/next.config.ts index 7efaba3..5c96377 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,101 +1,115 @@ import type { NextConfig } from 'next'; +import { PHASE_PRODUCTION_BUILD } from 'next/constants'; -const nextConfig: NextConfig = { - // Output as static site for GitHub Pages - output: 'export', +const nextConfig = (phase: string): NextConfig => { + // Determine if we should use basePath (production build, not Surge preview) + const isProductionBuild = phase === PHASE_PRODUCTION_BUILD; + const isSurgePreview = process.env.SURGE_PREVIEW === 'true'; + const shouldUseBasePath = isProductionBuild && !isSurgePreview; + const basePath = shouldUseBasePath ? '/github-profile-readme-generator' : ''; - // Base path for GitHub Pages (only in production AND not for Surge previews) - basePath: - process.env.NODE_ENV === 'production' && !process.env.SURGE_PREVIEW - ? '/github-profile-readme-generator' - : '', + return { + // Output as static site for GitHub Pages + output: 'export', - // Image optimization for static export - images: { - unoptimized: true, // Required for static export - }, + // Base path for GitHub Pages (only for production builds, not Surge previews) + basePath, - // Trailing slashes for better compatibility - trailingSlash: true, + // Asset prefix to ensure all assets use the correct path + assetPrefix: shouldUseBasePath ? '/github-profile-readme-generator/' : '', - // Enable strict mode for better error catching - reactStrictMode: true, - - // Enable experimental features for better performance - experimental: { - // Optimize CSS - optimizeCss: true, - // Enable optimized package imports for heavy libraries - optimizePackageImports: [ - 'framer-motion', - '@hookform/resolvers', - 'react-markdown', - 'remark-gfm', - 'rehype-raw', - 'rehype-sanitize', - 'zod', - 'zustand', - 'lucide-react', - '@headlessui/react', - ], - }, - - // Compiler options for better performance - compiler: { - // Remove console.log in production - removeConsole: process.env.NODE_ENV === 'production' ? { exclude: ['error', 'warn'] } : false, - // Enable React compiler optimizations - reactRemoveProperties: process.env.NODE_ENV === 'production', - }, - - // Optimize transpilation - transpilePackages: ['react-markdown', 'remark-gfm', 'rehype-raw', 'rehype-sanitize'], - - // Turbopack configuration (replaces webpack config) - turbopack: { - // Enable faster module resolution - resolveAlias: { - // Optimize common imports - '@': './src', + // Environment variables + env: { + NEXT_PUBLIC_BASE_PATH: basePath, }, - }, - // Webpack optimizations for development (only when not using Turbopack) - webpack: (config, { dev, isServer }) => { - if (dev && !isServer && !process.env.TURBOPACK) { - // Optimize development builds - config.optimization = { - ...config.optimization, - splitChunks: { - chunks: 'all', - cacheGroups: { - vendor: { - test: /[\\/]node_modules[\\/]/, - name: 'vendors', - chunks: 'all', - priority: 10, - }, - markdown: { - test: /[\\/]node_modules[\\/](react-markdown|remark-|rehype-)/, - name: 'markdown', - chunks: 'all', - priority: 20, + // Image optimization for static export + images: { + unoptimized: true, // Required for static export + }, + + // Trailing slashes for better compatibility + trailingSlash: true, + + // Enable strict mode for better error catching + reactStrictMode: true, + + // Enable experimental features for better performance + experimental: { + // Optimize CSS + optimizeCss: true, + // Enable optimized package imports for heavy libraries + optimizePackageImports: [ + 'framer-motion', + '@hookform/resolvers', + 'react-markdown', + 'remark-gfm', + 'rehype-raw', + 'rehype-sanitize', + 'zod', + 'zustand', + 'lucide-react', + '@headlessui/react', + ], + }, + + // Compiler options for better performance + compiler: { + // Remove console.log in production + removeConsole: isProductionBuild ? { exclude: ['error', 'warn'] } : false, + // Enable React compiler optimizations + reactRemoveProperties: isProductionBuild, + }, + + // Optimize transpilation + transpilePackages: ['react-markdown', 'remark-gfm', 'rehype-raw', 'rehype-sanitize'], + + // Turbopack configuration (replaces webpack config) + turbopack: { + // Enable faster module resolution + resolveAlias: { + // Optimize common imports + '@': './src', + }, + }, + + // Webpack optimizations for development (only when not using Turbopack) + webpack: (config, { dev, isServer }) => { + if (dev && !isServer && !process.env.TURBOPACK) { + // Optimize development builds + config.optimization = { + ...config.optimization, + splitChunks: { + chunks: 'all', + cacheGroups: { + vendor: { + test: /[\\/]node_modules[\\/]/, + name: 'vendors', + chunks: 'all', + priority: 10, + }, + markdown: { + test: /[\\/]node_modules[\\/](react-markdown|remark-|rehype-)/, + name: 'markdown', + chunks: 'all', + priority: 20, + }, }, }, - }, - }; + }; - // Enable faster rebuilds - config.cache = { - type: 'filesystem', - buildDependencies: { - config: [__filename], - }, - }; - } + // Enable faster rebuilds + config.cache = { + type: 'filesystem', + buildDependencies: { + config: [__filename], + }, + }; + } - return config; - }, + return config; + }, + }; }; export default nextConfig; diff --git a/src/app/layout.tsx b/src/app/layout.tsx index da1895b..daa5ffd 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -7,6 +7,7 @@ import { ToastProvider } from '@/components/ui/toast'; import { BuyMeACoffeeWidget } from '@/components/ui/buy-me-coffee'; import { ConditionalAnalytics } from '@/components/analytics/conditional-analytics'; import { CookieConsent } from '@/components/ui/cookie-consent'; +import { getAssetPath } from '@/lib/asset-path'; const robotoMono = Roboto_Mono({ variable: '--font-mono', @@ -83,11 +84,11 @@ export const metadata: Metadata = { icons: { icon: [ { url: '/favicon.ico', sizes: 'any' }, - { url: '/mdg.png', type: 'image/png' }, + { url: getAssetPath('/mdg.png'), type: 'image/png' }, ], - apple: '/mdg.png', + apple: getAssetPath('/mdg.png'), }, - manifest: '/manifest.json', + manifest: getAssetPath('/manifest.json'), robots: { index: true, follow: true, diff --git a/src/components/layout/footer.tsx b/src/components/layout/footer.tsx index 8c067d6..c429db1 100644 --- a/src/components/layout/footer.tsx +++ b/src/components/layout/footer.tsx @@ -1,5 +1,6 @@ import Link from 'next/link'; import Image from 'next/image'; +import { getAssetPath } from '@/lib/asset-path'; export function Footer() { return ( @@ -8,7 +9,7 @@ export function Footer() { {/* Logo Section */}
GitHub Profile README Generator Logo