full site update
This commit is contained in:
@@ -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>
|
Reference in New Issue
Block a user