feat: add security headers, update manifest and cache assets

This commit is contained in:
2025-05-16 12:04:37 +02:00
parent 31b897c375
commit 14209935f6
5 changed files with 81 additions and 27 deletions

23
public/_headers Normal file
View File

@ -0,0 +1,23 @@
/*
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' *.googleapis.com *.gstatic.com; style-src 'self' 'unsafe-inline' *.googleapis.com; img-src 'self' data: https:; font-src 'self' data: *.googleapis.com *.gstatic.com; connect-src 'self' *.googleapis.com; frame-ancestors 'none';
Strict-Transport-Security: max-age=31536000; includeSubDomains
/*.html
Cache-Control: public, max-age=0, must-revalidate
/assets/*
Cache-Control: public, max-age=31536000, immutable
/images/*
Cache-Control: public, max-age=31536000, immutable
/*.js
Cache-Control: public, max-age=31536000, immutable
/*.css
Cache-Control: public, max-age=31536000, immutable

View File

@ -1,12 +1,12 @@
{
"name": "Jan-Marlon Leibl | Fullstack Developer",
"short_name": "JL Portfolio",
"description": "Personal website and portfolio of Jan-Marlon Leibl, Fullstack Developer",
"name": "Jan-Marlon Leibl - Fullstack Developer",
"short_name": "Jan-Marlon Leibl",
"description": "Experienced Fullstack Developer specializing in PHP and TypeScript. Creating high-performance web applications and digital experiences with modern technologies.",
"start_url": "/",
"display": "standalone",
"background_color": "#0A0A0A",
"theme_color": "#0A0A0A",
"orientation": "portrait-primary",
"orientation": "portrait",
"screenshots": [
{
"src": "/screenshots/mobile.png",
@ -28,22 +28,33 @@
"name": "About Me",
"short_name": "About",
"description": "Learn more about Jan-Marlon Leibl",
"url": "/#about",
"icons": [{ "src": "/icons/about-icon.png", "sizes": "192x192" }]
"url": "/#about"
},
{
"name": "My Work",
"short_name": "Work",
"description": "View Jan-Marlon's portfolio projects",
"url": "/#work",
"icons": [{ "src": "/icons/work-icon.png", "sizes": "192x192" }]
"url": "/#work"
},
{
"name": "Contact",
"short_name": "Contact",
"description": "Get in touch with Jan-Marlon",
"url": "/#contact",
"icons": [{ "src": "/icons/contact-icon.png", "sizes": "192x192" }]
"url": "/#contact"
}
],
"icons": [
{
"src": "/profile-image-futu-style.jpg",
"sizes": "192x192",
"type": "image/jpeg",
"purpose": "any"
},
{
"src": "/profile-image-futu-style.jpg",
"sizes": "512x512",
"type": "image/jpeg",
"purpose": "any"
}
]
}

View File

@ -4,4 +4,7 @@ User-agent: *
Allow: /
# Optimize crawling
Crawl-delay: 10
Crawl-delay: 10
# Sitemaps
Sitemap: https://jleibl.net/sitemap-index.xml

View File

@ -1,21 +1,33 @@
const CACHE_NAME = "jleibl-portfolio-v1";
const PRECACHE_ASSETS = ["/", "/index.html"];
const AUTH_ASSETS = ["/manifest.json"];
const STYLE_ASSETS = ["/styles/global.css", "/styles/theme.css"];
const IMAGE_ASSETS = ["/images/profile-image-futu-style.jpg"];
const ALL_ASSETS = [...PRECACHE_ASSETS, ...AUTH_ASSETS, ...STYLE_ASSETS, ...IMAGE_ASSETS];
const CACHE_NAME = "jleibl-cache-v1";
const urlsToCache = [
"/",
"/index.html",
"/manifest.json",
"/profile-image-futu-style.jpg",
"/styles/global.css",
"/styles/theme.css",
];
self.addEventListener("install", (event) => {
self.skipWaiting();
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => {
console.log("Opened cache");
return cache.addAll(PRECACHE_ASSETS);
event.waitUntil(caches.open(CACHE_NAME).then((cache) => cache.addAll(urlsToCache)));
});
self.addEventListener("fetch", (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
if (response) {
return response;
}
return fetch(event.request).then((response) => {
if (!response || response.status !== 200 || response.type !== "basic") {
return response;
}
const responseToCache = response.clone();
caches.open(CACHE_NAME).then((cache) => {
cache.put(event.request, responseToCache);
});
return response;
});
})
);
});

View File

@ -110,3 +110,8 @@ const structuredDataWebsite = {
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link rel="manifest" href="/manifest.json" />
<link rel="preload" href="/profile-image-futu-style.jpg" as="image" />
<link rel="dns-prefetch" href="https://fonts.googleapis.com" />
<link rel="dns-prefetch" href="https://fonts.gstatic.com" />