chore: load assets with assetPrefix
This commit is contained in:
+100
-86
@@ -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;
|
||||
|
||||
+4
-3
@@ -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,
|
||||
|
||||
@@ -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 */}
|
||||
<div className="mb-8 flex items-center justify-center gap-3">
|
||||
<Image
|
||||
src="/mdg.png"
|
||||
src={getAssetPath('/mdg.png')}
|
||||
alt="GitHub Profile README Generator Logo"
|
||||
width={48}
|
||||
height={48}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { usePathname } from 'next/navigation';
|
||||
import { ThemeToggle } from '@/components/ui/theme-toggle';
|
||||
import { AccessibilityMenu } from '@/components/ui/accessibility-menu';
|
||||
import { GitHubStats } from '@/components/ui/github-stats';
|
||||
import { getAssetPath } from '@/lib/asset-path';
|
||||
|
||||
const navigation = [
|
||||
{ name: 'Generator', href: '/' },
|
||||
@@ -30,7 +31,7 @@ export function Header({}: HeaderProps = {}) {
|
||||
<div className="flex items-center gap-4">
|
||||
<Link href="/" prefetch={true} className="flex items-center gap-3 hover:opacity-80">
|
||||
<Image
|
||||
src="/mdg.png"
|
||||
src={getAssetPath('/mdg.png')}
|
||||
alt="GitHub Profile README Generator Logo"
|
||||
width={40}
|
||||
height={40}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Get the correct asset path with basePath for GitHub Pages
|
||||
* Uses NEXT_PUBLIC_BASE_PATH environment variable if set
|
||||
*/
|
||||
|
||||
export function getAssetPath(path: string): string {
|
||||
// Ensure path starts with /
|
||||
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
|
||||
|
||||
// Use NEXT_PUBLIC_BASE_PATH if set, otherwise detect based on build
|
||||
const basePath = process.env.NEXT_PUBLIC_BASE_PATH || '';
|
||||
|
||||
return `${basePath}${normalizedPath}`;
|
||||
}
|
||||
Reference in New Issue
Block a user