Skip to content

Commit aca9da2

Browse files
committed
Fix website loading issues
1 parent 3198122 commit aca9da2

File tree

12 files changed

+329
-65
lines changed

12 files changed

+329
-65
lines changed

next.config.ts

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,43 +7,55 @@ const nextConfig: NextConfig = {
77
trailingSlash: true,
88
skipTrailingSlashRedirect: true,
99
distDir: 'out',
10+
generateBuildId: () => 'build',
1011
// Custom domain - no basePath/assetPrefix needed
1112
}),
1213

13-
// Security Headers
14-
async headers() {
15-
return [
16-
{
17-
source: '/(.*)',
18-
headers: [
19-
{
20-
key: 'X-Frame-Options',
21-
value: 'DENY'
22-
},
23-
{
24-
key: 'X-Content-Type-Options',
25-
value: 'nosniff'
26-
},
27-
{
28-
key: 'Referrer-Policy',
29-
value: 'origin-when-cross-origin'
30-
},
31-
{
32-
key: 'X-DNS-Prefetch-Control',
33-
value: 'on'
34-
},
35-
{
36-
key: 'Strict-Transport-Security',
37-
value: 'max-age=31536000; includeSubDomains'
38-
},
39-
{
40-
key: 'Permissions-Policy',
41-
value: 'camera=(), microphone=(), geolocation=()'
42-
}
43-
]
44-
}
45-
]
46-
},
14+
// Security Headers (disabled for static export - handled by hosting provider)
15+
...(process.env.NODE_ENV !== 'production' && {
16+
async headers() {
17+
return [
18+
{
19+
source: '/(.*)',
20+
headers: [
21+
{
22+
key: 'X-Frame-Options',
23+
value: 'DENY'
24+
},
25+
{
26+
key: 'X-Content-Type-Options',
27+
value: 'nosniff'
28+
},
29+
{
30+
key: 'Referrer-Policy',
31+
value: 'origin-when-cross-origin'
32+
},
33+
{
34+
key: 'X-DNS-Prefetch-Control',
35+
value: 'on'
36+
},
37+
{
38+
key: 'Cache-Control',
39+
value: 'public, max-age=31536000, immutable'
40+
},
41+
{
42+
key: 'Permissions-Policy',
43+
value: 'camera=(), microphone=(), geolocation=()'
44+
}
45+
]
46+
},
47+
{
48+
source: '/_next/static/(.*)',
49+
headers: [
50+
{
51+
key: 'Cache-Control',
52+
value: 'public, max-age=31536000, immutable'
53+
}
54+
]
55+
}
56+
]
57+
}
58+
}),
4759

4860
// Performance optimizations
4961
compress: true,

public/favicon.ico

31.6 KB
Binary file not shown.

public/icon-192.png

31.6 KB
Loading

public/icon-512.png

127 KB
Loading

public/manifest.json

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
11
{
22
"name": "Samet Dulger - Full Stack Developer",
33
"short_name": "Samet Dulger",
4-
"description": "Full Stack Developer Portfolio",
4+
"description": "Full Stack Developer Portfolio - .NET & React Expert",
55
"start_url": "/",
66
"display": "standalone",
77
"background_color": "#000000",
88
"theme_color": "#000000",
9+
"orientation": "portrait-primary",
10+
"scope": "/",
11+
"lang": "en",
912
"icons": [
1013
{
11-
"src": "/icon.png",
12-
"sizes": "any",
13-
"type": "image/png"
14+
"src": "/icon-192.png",
15+
"sizes": "192x192",
16+
"type": "image/png",
17+
"purpose": "any"
18+
},
19+
{
20+
"src": "/icon-512.png",
21+
"sizes": "512x512",
22+
"type": "image/png",
23+
"purpose": "maskable"
1424
}
15-
]
25+
],
26+
"categories": ["productivity", "developer-tools", "portfolio"]
1627
}

public/sw.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Service Worker for font caching and offline support
2+
const CACHE_NAME = 'sametdulger-v1';
3+
const FONT_CACHE_NAME = 'fonts-v1';
4+
5+
// Cache fonts and critical assets
6+
const FONTS_TO_CACHE = [
7+
'/_next/static/media/',
8+
];
9+
10+
const CRITICAL_ASSETS = [
11+
'/',
12+
'/manifest.json',
13+
'/_next/static/css/',
14+
];
15+
16+
self.addEventListener('install', (event) => {
17+
event.waitUntil(
18+
Promise.all([
19+
caches.open(CACHE_NAME).then((cache) => {
20+
return cache.addAll(CRITICAL_ASSETS).catch(err => {
21+
console.warn('Cache addAll failed:', err);
22+
});
23+
}),
24+
caches.open(FONT_CACHE_NAME)
25+
])
26+
);
27+
self.skipWaiting();
28+
});
29+
30+
self.addEventListener('activate', (event) => {
31+
event.waitUntil(
32+
caches.keys().then((cacheNames) => {
33+
return Promise.all(
34+
cacheNames.map((cacheName) => {
35+
if (cacheName !== CACHE_NAME && cacheName !== FONT_CACHE_NAME) {
36+
return caches.delete(cacheName);
37+
}
38+
})
39+
);
40+
})
41+
);
42+
self.clients.claim();
43+
});
44+
45+
self.addEventListener('fetch', (event) => {
46+
const { request } = event;
47+
const url = new URL(request.url);
48+
49+
// Handle font requests with aggressive caching
50+
if (request.destination === 'font' || url.pathname.includes('.woff2') || url.pathname.includes('.woff')) {
51+
event.respondWith(
52+
caches.open(FONT_CACHE_NAME).then((cache) => {
53+
return cache.match(request).then((cachedResponse) => {
54+
if (cachedResponse) {
55+
return cachedResponse;
56+
}
57+
58+
return fetch(request).then((response) => {
59+
// Only cache successful font responses
60+
if (response.status === 200) {
61+
cache.put(request, response.clone());
62+
}
63+
return response;
64+
}).catch(() => {
65+
// Return a basic response if font fails to load
66+
return new Response('', {
67+
status: 204,
68+
statusText: 'Font not available'
69+
});
70+
});
71+
});
72+
})
73+
);
74+
return;
75+
}
76+
77+
// Handle other requests with network-first strategy
78+
if (url.origin === location.origin) {
79+
event.respondWith(
80+
fetch(request).catch(() => {
81+
return caches.match(request);
82+
})
83+
);
84+
}
85+
});

src/app/font-loader.tsx

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
'use client'
2+
3+
import { useEffect } from 'react'
4+
5+
export function FontLoader() {
6+
useEffect(() => {
7+
// Font loading error handling
8+
const handleFontLoadError = () => {
9+
// Add fallback font loading logic
10+
const style = document.createElement('style')
11+
style.textContent = `
12+
body {
13+
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
14+
}
15+
.font-mono {
16+
font-family: Monaco, Consolas, 'Courier New', monospace !important;
17+
}
18+
`
19+
document.head.appendChild(style)
20+
}
21+
22+
// Check if fonts are loaded
23+
if ('fonts' in document) {
24+
document.fonts.ready.then(() => {
25+
console.log('All fonts loaded successfully')
26+
}).catch((error) => {
27+
console.warn('Font loading failed, using fallback fonts:', error)
28+
handleFontLoadError()
29+
})
30+
31+
// Listen for font loading events
32+
document.fonts.addEventListener('loadingdone', (event) => {
33+
console.log(`Font loading completed: ${event.fontfaces.length} fonts loaded`)
34+
})
35+
36+
document.fonts.addEventListener('loadingerror', (event) => {
37+
console.warn('Font loading error detected, applying fallbacks')
38+
handleFontLoadError()
39+
})
40+
}
41+
42+
// Fallback timeout - if fonts don't load within 3 seconds, use fallbacks
43+
const fontTimeout = setTimeout(() => {
44+
if (document.fonts && document.fonts.status !== 'loaded') {
45+
console.warn('Font loading timeout, using fallback fonts')
46+
handleFontLoadError()
47+
}
48+
}, 3000)
49+
50+
return () => {
51+
clearTimeout(fontTimeout)
52+
}
53+
}, [])
54+
55+
return null
56+
}

src/app/globals.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@
1010

1111
body {
1212
line-height: 1.6;
13+
font-display: swap; /* Ensure font-display swap for all fonts */
14+
}
15+
16+
/* Font loading optimizations */
17+
.font-optimized {
18+
font-synthesis: none;
19+
text-rendering: optimizeLegibility;
20+
-webkit-font-smoothing: antialiased;
21+
-moz-osx-font-smoothing: grayscale;
1322
}
1423

1524
/* Critical above-the-fold styles */

src/app/icon.png

-17.2 KB
Binary file not shown.

0 commit comments

Comments
 (0)