full site update

This commit is contained in:
2025-07-24 18:46:24 +02:00
parent bfe2b90d8d
commit 37a6e0ab31
6912 changed files with 540482 additions and 361712 deletions

View File

@@ -1,8 +1,6 @@
---
import { SITE } from '../site.config';
import i18next, { t } from "i18next";
import { Trans, HeadHrefLangs } from "astro-i18next/components";
import { localizePath } from "astro-i18next";
import { getLangFromUrl, useTranslations } from '../utils/i18n';
import '../styles/global.css';
export interface Props {
@@ -10,24 +8,29 @@ export interface Props {
description?: string;
image?: string;
keywords?: string;
noindex?: boolean;
nofollow?: boolean;
}
const lang = getLangFromUrl(Astro.url);
const t = await useTranslations(lang);
const {
title = t('site.title'),
description = t('site.description'),
image = SITE.ogImage,
keywords = t('meta.keywords')
keywords = t('meta.keywords'),
noindex = false,
nofollow = false
} = Astro.props;
const lang = Astro.currentLocale || 'en';
// Safe URL creation with fallbacks
let canonicalURL;
let ogImageURL;
let twitterImageURL;
try {
const siteURL = Astro.site || new URL('http://localhost:4321');
const siteURL = Astro.site || new URL('https://tiber365.it');
canonicalURL = new URL(Astro.url.pathname, siteURL);
ogImageURL = new URL(image, siteURL);
twitterImageURL = new URL(image, siteURL);
@@ -41,35 +44,74 @@ try {
const fullTitle = title === t('site.title') ? title : `${title} | ${t('site.title')}`;
// Get all available locales
const locales = ["en", "nl", "it"];
// All available locales
const locales = ["en", "nl", "de", "fr"];
// Generate structured data
const structuredData = {
"@context": "https://schema.org",
"@type": "Organization",
"name": t('site.title'),
"description": description,
"url": SITE.url,
"logo": `${SITE.url}/images/TIBER365.png`,
"sameAs": [
"https://support.tiber365.it"
],
"contactPoint": {
"@type": "ContactPoint",
"contactType": "customer service",
"availableLanguage": ["English", "Dutch", "German", "French"]
},
"address": {
"@type": "PostalAddress",
"addressCountry": "IT"
},
"serviceArea": {
"@type": "Country",
"name": "Italy"
}
};
---
<!doctype html>
<html lang={lang} class="scroll-smooth">
<head>
<meta charset="UTF-8" />
<meta name="description" content={description} />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="generator" content={Astro.generator} />
{keywords && <meta name="keywords" content={keywords} />}
<!-- Font Preloading -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link rel="preload" href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Poppins:wght@400;500;600;700&display=swap" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Poppins:wght@400;500;600;700&display=swap" /></noscript>
<!-- DNS Prefetch -->
<link rel="dns-prefetch" href="//fonts.googleapis.com" />
<link rel="dns-prefetch" href="//fonts.gstatic.com" />
<!-- SEO Meta Tags -->
<title>{fullTitle}</title>
<meta name="description" content={description} />
<meta name="keywords" content={keywords} />
<meta name="author" content={SITE.author} />
<!-- Robots Meta -->
{noindex && <meta name="robots" content="noindex" />}
{nofollow && <meta name="robots" content="nofollow" />}
{!noindex && !nofollow && <meta name="robots" content="index, follow" />}
<!-- Canonical URL -->
<link rel="canonical" href={canonicalURL} />
<!-- Primary Meta Tags -->
<title>{fullTitle}</title>
<meta name="title" content={fullTitle} />
<meta name="description" content={description} />
<meta name="author" content={SITE.author} />
<!-- Prevent automatic language redirects -->
<!-- Language and Localization -->
<meta name="google" content="notranslate" />
<meta http-equiv="Content-Language" content={lang} />
<!-- Theme Color -->
<meta name="theme-color" content="#ffffff" />
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)" />
<meta name="theme-color" content="#1f2937" media="(prefers-color-scheme: dark)" />
<meta name="msapplication-TileColor" content="#3b82f6" />
<!-- Open Graph / Facebook -->
@@ -78,41 +120,66 @@ const locales = ["en", "nl", "it"];
<meta property="og:title" content={fullTitle} />
<meta property="og:description" content={description} />
<meta property="og:image" content={ogImageURL} />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:site_name" content={t('site.title')} />
<meta property="og:locale" content={lang === 'en' ? 'en_US' : lang === 'nl' ? 'nl_NL' : 'it_IT'} />
<meta property="og:locale" content={lang === 'en' ? 'en_US' : lang === 'nl' ? 'nl_NL' : lang === 'de' ? 'de_DE' : 'fr_FR'} />
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:url" content={canonicalURL} />
<meta property="twitter:title" content={fullTitle} />
<meta property="twitter:description" content={description} />
<meta property="twitter:image" content={twitterImageURL} />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:url" content={canonicalURL} />
<meta name="twitter:title" content={fullTitle} />
<meta name="twitter:description" content={description} />
<meta name="twitter:image" content={twitterImageURL} />
<meta name="twitter:creator" content="@tiber365" />
<!-- Favicons -->
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="apple-touch-icon" href="/favicon.svg" />
<link rel="manifest" href="/manifest.json" />
<!-- Language alternates -->
{locales.map(locale => (
<link
rel="alternate"
hreflang={locale}
href={new URL(localizePath(Astro.url.pathname, locale), Astro.site).toString()}
/>
))}
{locales.map(locale => {
const currentPath = Astro.url.pathname.replace(/^\/[a-z]{2}\//, '/').replace(/^\/[a-z]{2}$/, '/');
const localePath = locale === 'en' ? currentPath : `/${locale}${currentPath}`;
const localeUrl = new URL(localePath, SITE.url).toString();
return (
<link
rel="alternate"
hreflang={locale}
href={localeUrl}
/>
);
})}
<!-- Structured Data -->
<script type="application/ld+json" set:html={JSON.stringify(structuredData)} />
</head>
<body class="min-h-screen bg-background text-foreground">
<slot />
<!-- Initialize animations -->
<!-- Initialize animations and service worker -->
<script>
import { initScrollAnimations } from '../utils/animations';
import { initTheme } from '../utils/theme';
import { initPerformanceMonitoring } from '../utils/performance';
document.addEventListener('DOMContentLoaded', () => {
initTheme();
initScrollAnimations();
initPerformanceMonitoring();
// Register service worker
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then((registration) => {
console.log('SW registered: ', registration);
})
.catch((registrationError) => {
console.log('SW registration failed: ', registrationError);
});
}
});
</script>
</body>
</html>
</html>