Added homepage and moved old homepage to aboutme page
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
---
|
||||
import { Icon } from 'astro-icon/components';
|
||||
import { supportedLanguages } from '~/i18n/translations';
|
||||
|
||||
interface Props {
|
||||
currentLang: string;
|
||||
@@ -7,8 +8,6 @@ interface Props {
|
||||
|
||||
const { currentLang } = Astro.props;
|
||||
|
||||
import { supportedLanguages } from '~/i18n/translations';
|
||||
|
||||
type SupportedLanguage = typeof supportedLanguages[number];
|
||||
|
||||
const languages = [
|
||||
@@ -121,13 +120,13 @@ const currentLanguage = languages.find(lang => lang.code === currentLang) || lan
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
<script define:vars={{ supportedLanguages }}>
|
||||
function setupLanguageDropdown() {
|
||||
const button = document.querySelector<HTMLButtonElement>('#menu-button');
|
||||
const menu = document.querySelector<HTMLDivElement>('#language-menu');
|
||||
const chevronIcon = document.querySelector<HTMLElement>('#chevron-icon');
|
||||
const selectedLanguageText = document.querySelector<HTMLElement>('#selected-language');
|
||||
const languageButtons = document.querySelectorAll<HTMLButtonElement>('[data-lang-code]');
|
||||
const button = document.querySelector('#menu-button');
|
||||
const menu = document.querySelector('#language-menu');
|
||||
const chevronIcon = document.querySelector('#chevron-icon');
|
||||
const selectedLanguageText = document.querySelector('#selected-language');
|
||||
const languageButtons = document.querySelectorAll('[data-lang-code]');
|
||||
|
||||
if (!button || !menu || !chevronIcon || !selectedLanguageText) {
|
||||
return;
|
||||
@@ -184,7 +183,7 @@ const currentLanguage = languages.find(lang => lang.code === currentLang) || lan
|
||||
closeMenu();
|
||||
|
||||
// Toggle menu
|
||||
button.addEventListener('click', (e: MouseEvent) => {
|
||||
button.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
if (isOpen) {
|
||||
closeMenu();
|
||||
@@ -193,7 +192,7 @@ const currentLanguage = languages.find(lang => lang.code === currentLang) || lan
|
||||
// Focus the first menu item for better keyboard navigation
|
||||
const firstMenuItem = menu.querySelector('button[role="menuitem"]');
|
||||
if (firstMenuItem) {
|
||||
(firstMenuItem as HTMLElement).focus();
|
||||
firstMenuItem.focus();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -205,7 +204,7 @@ const currentLanguage = languages.find(lang => lang.code === currentLang) || lan
|
||||
if (!langCode) return;
|
||||
|
||||
// Update button text and icon
|
||||
const langName = langButton.textContent?.trim();
|
||||
const langName = langButton.textContent ? langButton.textContent.trim() : '';
|
||||
const flagIcon = langButton.querySelector('svg');
|
||||
if (langName && flagIcon) {
|
||||
selectedLanguageText.textContent = langName;
|
||||
@@ -218,27 +217,84 @@ const currentLanguage = languages.find(lang => lang.code === currentLang) || lan
|
||||
// Close menu
|
||||
closeMenu();
|
||||
|
||||
// Get current path and redirect
|
||||
const currentPath = window.location.pathname.replace(/\/$/, '');
|
||||
// Get current URL information
|
||||
const currentUrl = new URL(window.location.href);
|
||||
const currentPath = currentUrl.pathname.replace(/\/$/, '');
|
||||
const currentHash = currentUrl.hash;
|
||||
const pathSegments = currentPath.split('/').filter(Boolean);
|
||||
const isBlogPost = pathSegments.length > 0 && !['en', 'nl', 'de'].includes(pathSegments[0]);
|
||||
const pathWithoutLang = pathSegments.length > 1 ? `/${pathSegments.slice(1).join('/')}`.replace(/\/$/, '') : '';
|
||||
|
||||
// Redirect to new language path
|
||||
window.location.href = isBlogPost ? `/${langCode}` : `/${langCode}${pathWithoutLang || ''}`;
|
||||
// Check if we're on a language-specific path
|
||||
const isLangPath = supportedLanguages.includes(pathSegments[0]);
|
||||
|
||||
// Get the previous language code
|
||||
const previousLangCode = isLangPath ? pathSegments[0] : 'en';
|
||||
|
||||
// Extract the page path without language
|
||||
let pagePath = '';
|
||||
if (isLangPath && pathSegments.length > 1) {
|
||||
// If we're on a language-specific path, get everything after the language code
|
||||
pagePath = `/${pathSegments.slice(1).join('/')}`;
|
||||
} else if (!isLangPath && pathSegments.length > 0) {
|
||||
// If we're not on a language-specific path, use the current path
|
||||
pagePath = `/${pathSegments.join('/')}`;
|
||||
}
|
||||
|
||||
// Handle special case for root path
|
||||
const isRootPath = pathSegments.length === 0 || (isLangPath && pathSegments.length === 1);
|
||||
|
||||
// Construct the new URL
|
||||
let newUrl = isRootPath ? `/${langCode}` : `/${langCode}${pagePath}`;
|
||||
|
||||
// Clean up any potential double slashes
|
||||
newUrl = newUrl.replace(/\/+/g, '/');
|
||||
|
||||
// Append hash fragment if it exists
|
||||
if (currentHash) {
|
||||
newUrl += currentHash;
|
||||
}
|
||||
|
||||
// Store the language preference in localStorage and cookies
|
||||
if (window.languageUtils) {
|
||||
window.languageUtils.storeLanguagePreference(langCode);
|
||||
} else {
|
||||
// Fallback if languageUtils is not available
|
||||
localStorage.setItem('preferredLanguage', langCode);
|
||||
|
||||
// Also set a cookie for server-side detection
|
||||
const expirationDate = new Date();
|
||||
expirationDate.setFullYear(expirationDate.getFullYear() + 1);
|
||||
document.cookie = `preferredLanguage=${langCode}; expires=${expirationDate.toUTCString()}; path=/; SameSite=Lax`;
|
||||
}
|
||||
|
||||
// Dispatch the language changed event
|
||||
const reloadEvent = new CustomEvent('languageChanged', {
|
||||
detail: {
|
||||
langCode,
|
||||
previousLangCode,
|
||||
path: newUrl,
|
||||
willReload: true
|
||||
}
|
||||
});
|
||||
document.dispatchEvent(reloadEvent);
|
||||
|
||||
// Construct the full URL
|
||||
const newFullUrl = `${window.location.origin}${newUrl}`;
|
||||
|
||||
// Reload the page to ensure all content is updated to the new language
|
||||
window.location.href = newFullUrl;
|
||||
});
|
||||
});
|
||||
|
||||
// Close when clicking outside
|
||||
document.addEventListener('click', (e: MouseEvent) => {
|
||||
const target = e.target as HTMLElement;
|
||||
document.addEventListener('click', (e) => {
|
||||
const target = e.target;
|
||||
if (isOpen && !menu.contains(target) && !button.contains(target)) {
|
||||
closeMenu();
|
||||
}
|
||||
});
|
||||
|
||||
// Handle keyboard navigation
|
||||
document.addEventListener('keydown', (e: KeyboardEvent) => {
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape' && isOpen) {
|
||||
closeMenu();
|
||||
button.focus();
|
||||
@@ -257,7 +313,7 @@ const currentLanguage = languages.find(lang => lang.code === currentLang) || lan
|
||||
newIndex = currentIndex > 0 ? currentIndex - 1 : menuItems.length - 1;
|
||||
}
|
||||
|
||||
(menuItems[newIndex] as HTMLElement).focus();
|
||||
menuItems[newIndex].focus();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -271,4 +327,10 @@ const currentLanguage = languages.find(lang => lang.code === currentLang) || lan
|
||||
|
||||
// Re-run setup when the page content is updated (e.g., after navigation)
|
||||
document.addEventListener('astro:page-load', setupLanguageDropdown);
|
||||
|
||||
// Listen for popstate events (browser back/forward buttons)
|
||||
window.addEventListener('popstate', (_event) => {
|
||||
// No need to manually update anything here as the browser will
|
||||
// automatically load the correct URL, and Astro will handle the rendering
|
||||
});
|
||||
</script>
|
112
src/components/LanguagePersistence.astro
Normal file
112
src/components/LanguagePersistence.astro
Normal file
@@ -0,0 +1,112 @@
|
||||
---
|
||||
// This component handles the synchronization between localStorage and cookies
|
||||
// for language persistence across page loads and navigation
|
||||
|
||||
// Extend Window interface to include languageUtils
|
||||
declare global {
|
||||
interface Window {
|
||||
languageUtils?: {
|
||||
getStoredLanguage: () => string | null;
|
||||
storeLanguagePreference: (langCode: string) => void;
|
||||
};
|
||||
}
|
||||
}
|
||||
---
|
||||
|
||||
<script>
|
||||
function setupLanguagePersistence() {
|
||||
// Function to get language from localStorage
|
||||
function getStoredLanguage() {
|
||||
return localStorage.getItem('preferredLanguage');
|
||||
}
|
||||
|
||||
// Function to set a cookie with the language preference
|
||||
function setLanguageCookie(langCode) {
|
||||
// Set cookie with a long expiration (1 year)
|
||||
const expirationDate = new Date();
|
||||
expirationDate.setFullYear(expirationDate.getFullYear() + 1);
|
||||
document.cookie = `preferredLanguage=${langCode}; expires=${expirationDate.toUTCString()}; path=/; SameSite=Lax`;
|
||||
}
|
||||
|
||||
// Function to get language from cookie
|
||||
function getLanguageFromCookie() {
|
||||
const cookies = document.cookie.split(';');
|
||||
for (let i = 0; i < cookies.length; i++) {
|
||||
const cookie = cookies[i].trim();
|
||||
if (cookie.startsWith('preferredLanguage=')) {
|
||||
return cookie.substring('preferredLanguage='.length);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Function to get language from URL
|
||||
function getLanguageFromURL() {
|
||||
const pathSegments = window.location.pathname.split('/').filter(Boolean);
|
||||
const supportedLanguages = ['en', 'nl', 'de', 'fr'];
|
||||
if (pathSegments.length > 0 && supportedLanguages.includes(pathSegments[0])) {
|
||||
return pathSegments[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// On page load, sync language between URL, localStorage and cookie
|
||||
const urlLanguage = getLanguageFromURL();
|
||||
const storedLanguage = getStoredLanguage();
|
||||
const cookieLanguage = getLanguageFromCookie();
|
||||
|
||||
// URL language takes precedence if it exists
|
||||
if (urlLanguage) {
|
||||
// If URL has a language, make sure localStorage and cookie match it
|
||||
if (!storedLanguage || storedLanguage !== urlLanguage) {
|
||||
localStorage.setItem('preferredLanguage', urlLanguage);
|
||||
}
|
||||
if (!cookieLanguage || cookieLanguage !== urlLanguage) {
|
||||
setLanguageCookie(urlLanguage);
|
||||
}
|
||||
} else if (storedLanguage && !cookieLanguage) {
|
||||
// If language is in localStorage but not in cookie, update cookie
|
||||
setLanguageCookie(storedLanguage);
|
||||
} else if (!storedLanguage && cookieLanguage) {
|
||||
// If language is in cookie but not in localStorage, update localStorage
|
||||
localStorage.setItem('preferredLanguage', cookieLanguage);
|
||||
} else if (storedLanguage && cookieLanguage && storedLanguage !== cookieLanguage) {
|
||||
// If both exist but are different, prefer localStorage
|
||||
setLanguageCookie(storedLanguage);
|
||||
}
|
||||
|
||||
// Listen for language changes and update the cookie
|
||||
document.addEventListener('languageChanged', (event: CustomEvent) => {
|
||||
if (event.detail && event.detail.langCode) {
|
||||
setLanguageCookie(event.detail.langCode);
|
||||
localStorage.setItem('preferredLanguage', event.detail.langCode);
|
||||
}
|
||||
});
|
||||
|
||||
// When localStorage changes (e.g., from another tab), update the cookie
|
||||
window.addEventListener('storage', (event) => {
|
||||
if (event.key === 'preferredLanguage' && event.newValue) {
|
||||
setLanguageCookie(event.newValue);
|
||||
}
|
||||
});
|
||||
|
||||
// Make language utility functions available globally
|
||||
window.languageUtils = {
|
||||
getStoredLanguage: getStoredLanguage,
|
||||
storeLanguagePreference: (langCode) => {
|
||||
localStorage.setItem('preferredLanguage', langCode);
|
||||
setLanguageCookie(langCode);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Run setup when DOM is ready
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', setupLanguagePersistence);
|
||||
} else {
|
||||
setupLanguagePersistence();
|
||||
}
|
||||
|
||||
// Re-run setup when the page content is updated (e.g., after navigation)
|
||||
document.addEventListener('astro:page-load', setupLanguagePersistence);
|
||||
</script>
|
@@ -159,6 +159,205 @@ import { UI } from 'astrowind:config';
|
||||
onLoad();
|
||||
onPageShow();
|
||||
});
|
||||
|
||||
// Handle smooth scrolling for anchor links across all pages
|
||||
function setupSmoothScrolling() {
|
||||
// Handle links that start with # (pure anchor links)
|
||||
document.querySelectorAll('a[href^="#"]:not([href="#"])').forEach(anchor => {
|
||||
anchor.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
const targetId = this.getAttribute('href').substring(1);
|
||||
const targetElement = document.getElementById(targetId);
|
||||
|
||||
if (targetElement) {
|
||||
window.scrollTo({
|
||||
top: targetElement.offsetTop - 50, // Offset for header
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Handle links that contain # but don't start with it (page + anchor)
|
||||
document.querySelectorAll('a[href*="#"]:not([href^="#"])').forEach(anchor => {
|
||||
anchor.addEventListener('click', function (e) {
|
||||
const href = this.getAttribute('href');
|
||||
const isHashLink = this.getAttribute('data-hash-link') === 'true';
|
||||
|
||||
// Check if this is a link to the current page
|
||||
// First, extract the path part (before the hash)
|
||||
const hrefPath = href.split('#')[0];
|
||||
const currentPath = window.location.pathname;
|
||||
|
||||
// Consider it's the current page if:
|
||||
// 1. The path matches exactly
|
||||
// 2. The href is just a hash (like '/#services')
|
||||
// 3. The href path is '/' and we're on the homepage
|
||||
const isCurrentPage =
|
||||
currentPath === hrefPath ||
|
||||
hrefPath === '' ||
|
||||
(hrefPath === '/' && (currentPath === '/' || currentPath.endsWith('/index.html')));
|
||||
|
||||
// For hash links, we want to update the URL and scroll to the element
|
||||
if (isHashLink || isCurrentPage) {
|
||||
e.preventDefault();
|
||||
|
||||
const hashIndex = href.indexOf('#');
|
||||
if (hashIndex !== -1) {
|
||||
const targetId = href.substring(hashIndex + 1);
|
||||
const targetElement = document.getElementById(targetId);
|
||||
|
||||
if (targetElement) {
|
||||
// Update the URL with the hash fragment
|
||||
history.pushState(null, null, href);
|
||||
|
||||
window.scrollTo({
|
||||
top: targetElement.offsetTop - 50, // Offset for header
|
||||
behavior: 'smooth'
|
||||
});
|
||||
} else {
|
||||
// If the target element doesn't exist on the current page, navigate to the page
|
||||
window.location.href = href;
|
||||
}
|
||||
} else {
|
||||
// If there's no hash fragment, just navigate to the page
|
||||
window.location.href = href;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Handle language changes and hash navigation
|
||||
function setupLanguageNavigation() {
|
||||
// Initialize language preference from localStorage or default to 'en'
|
||||
function getStoredLanguage() {
|
||||
return localStorage.getItem('preferredLanguage') || 'en';
|
||||
}
|
||||
|
||||
// Store language preference in localStorage
|
||||
function storeLanguagePreference(langCode) {
|
||||
localStorage.setItem('preferredLanguage', langCode);
|
||||
console.log('Language preference stored:', langCode);
|
||||
}
|
||||
|
||||
// Function to update URLs with the current language
|
||||
function updateUrlsWithLanguage() {
|
||||
const currentLang = getStoredLanguage();
|
||||
const supportedLanguages = ['en', 'nl', 'de', 'fr'];
|
||||
|
||||
// Update all internal links to include the language prefix
|
||||
document.querySelectorAll('a[href^="/"]:not([href^="//"])').forEach(link => {
|
||||
const href = link.getAttribute('href');
|
||||
if (!href) return;
|
||||
|
||||
// Skip hash-only links (e.g., "#services")
|
||||
if (href.startsWith('#')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Extract hash fragment if present
|
||||
let hashFragment = '';
|
||||
let pathWithoutHash = href;
|
||||
|
||||
if (href.includes('#')) {
|
||||
const parts = href.split('#');
|
||||
pathWithoutHash = parts[0];
|
||||
hashFragment = '#' + parts[1];
|
||||
}
|
||||
|
||||
// Parse the URL path (without hash) to check for existing language code
|
||||
const pathSegments = pathWithoutHash.split('/').filter(Boolean);
|
||||
const hasLanguagePrefix = pathSegments.length > 0 && supportedLanguages.includes(pathSegments[0]);
|
||||
|
||||
// If it already has a language prefix but it's different from the current language,
|
||||
// update it to the current language
|
||||
if (hasLanguagePrefix && pathSegments[0] !== currentLang) {
|
||||
// Replace the existing language prefix with the current one
|
||||
pathSegments[0] = currentLang;
|
||||
const newPath = '/' + pathSegments.join('/');
|
||||
|
||||
// Set the new href with the hash fragment (if any)
|
||||
link.setAttribute('href', newPath + hashFragment);
|
||||
return;
|
||||
}
|
||||
|
||||
// If it doesn't have a language prefix, add the current language
|
||||
if (!hasLanguagePrefix) {
|
||||
// Create the new path with the language prefix
|
||||
const newPath = pathWithoutHash === '/' ?
|
||||
`/${currentLang}` :
|
||||
`/${currentLang}${pathWithoutHash}`;
|
||||
|
||||
// Set the new href with the hash fragment (if any)
|
||||
link.setAttribute('href', newPath + hashFragment);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Listen for the custom languageChanged event
|
||||
document.addEventListener('languageChanged', (event) => {
|
||||
// Store the selected language in localStorage
|
||||
if (event.detail && event.detail.langCode) {
|
||||
storeLanguagePreference(event.detail.langCode);
|
||||
console.log('Language changed:', event.detail);
|
||||
|
||||
// Always update all internal links with the new language
|
||||
// regardless of whether we're doing a full page reload
|
||||
updateUrlsWithLanguage();
|
||||
}
|
||||
});
|
||||
|
||||
// Process links when the page loads
|
||||
updateUrlsWithLanguage();
|
||||
|
||||
// Process links after client-side navigation
|
||||
document.addEventListener('astro:page-load', () => {
|
||||
// Short delay to ensure DOM is fully updated
|
||||
setTimeout(updateUrlsWithLanguage, 0);
|
||||
});
|
||||
|
||||
// Also update links when the DOM content is loaded
|
||||
document.addEventListener('DOMContentLoaded', updateUrlsWithLanguage);
|
||||
|
||||
// Check for hash in URL on page load and scroll to it
|
||||
function scrollToHashOnLoad() {
|
||||
if (window.location.hash) {
|
||||
const targetId = window.location.hash.substring(1);
|
||||
const targetElement = document.getElementById(targetId);
|
||||
|
||||
if (targetElement) {
|
||||
// Use setTimeout to ensure the page has fully loaded
|
||||
setTimeout(() => {
|
||||
window.scrollTo({
|
||||
top: targetElement.offsetTop - 50, // Offset for header
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scrollToHashOnLoad();
|
||||
|
||||
// Make language functions available globally
|
||||
window.languageUtils = {
|
||||
getStoredLanguage,
|
||||
storeLanguagePreference
|
||||
};
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
setupSmoothScrolling();
|
||||
setupLanguageNavigation();
|
||||
});
|
||||
|
||||
// Re-attach event listeners after page transitions
|
||||
document.addEventListener('astro:after-swap', () => {
|
||||
setupSmoothScrolling();
|
||||
setupLanguageNavigation();
|
||||
});
|
||||
</script>
|
||||
|
||||
<script is:inline>
|
||||
|
@@ -2,6 +2,7 @@
|
||||
import { Icon } from 'astro-icon/components';
|
||||
import { SITE } from 'astrowind:config';
|
||||
import { getHomePermalink } from '~/utils/permalinks';
|
||||
import { getFooterData } from '~/navigation';
|
||||
|
||||
interface Link {
|
||||
text?: string;
|
||||
@@ -17,13 +18,50 @@ interface Links {
|
||||
|
||||
export interface Props {
|
||||
links?: Array<Links>;
|
||||
secondaryLinks: Array<Link>;
|
||||
socialLinks: Array<Link>;
|
||||
secondaryLinks?: Array<Link>;
|
||||
socialLinks?: Array<Link>;
|
||||
footNote?: string;
|
||||
theme?: string;
|
||||
}
|
||||
|
||||
const { socialLinks = [], theme = 'light' } = Astro.props;
|
||||
import { supportedLanguages } from '~/i18n/translations';
|
||||
|
||||
// Define the type for supported languages
|
||||
type SupportedLanguage = typeof supportedLanguages[number];
|
||||
|
||||
// Get current language from URL
|
||||
const currentPath = `/${Astro.url.pathname.replace(/^\/+|\/+$/g, '')}`;
|
||||
const pathSegments = currentPath.split('/').filter(Boolean);
|
||||
|
||||
// Check for language in URL path
|
||||
let currentLang = pathSegments[0] && supportedLanguages.includes(pathSegments[0] as SupportedLanguage)
|
||||
? pathSegments[0] as SupportedLanguage
|
||||
: null;
|
||||
|
||||
// If no language in URL, check cookies
|
||||
if (!currentLang) {
|
||||
const cookies = Astro.request.headers.get('cookie') || '';
|
||||
const cookieLanguage = cookies.split(';')
|
||||
.map(cookie => cookie.trim())
|
||||
.find(cookie => cookie.startsWith('preferredLanguage='))
|
||||
?.split('=')[1];
|
||||
|
||||
if (cookieLanguage && supportedLanguages.includes(cookieLanguage as SupportedLanguage)) {
|
||||
currentLang = cookieLanguage as SupportedLanguage;
|
||||
} else {
|
||||
// Default to English if no language is found
|
||||
currentLang = 'en';
|
||||
}
|
||||
}
|
||||
|
||||
// Get translated footer data
|
||||
const footerData = getFooterData(currentLang);
|
||||
|
||||
const {
|
||||
secondaryLinks = footerData.secondaryLinks,
|
||||
socialLinks = footerData.socialLinks,
|
||||
theme = 'light'
|
||||
} = Astro.props;
|
||||
---
|
||||
|
||||
<footer class:list={[{ dark: theme === 'dark' }, 'relative border-t border-gray-200 dark:border-slate-800 not-prose']}>
|
||||
@@ -38,13 +76,17 @@ const { socialLinks = [], theme = 'light' } = Astro.props;
|
||||
<!-- Site Title with Terms & Privacy Links -->
|
||||
<div class="flex flex-col items-start space-y-2">
|
||||
<!-- Site Title -->
|
||||
<a class="inline-block font-bold text-xl" href={getHomePermalink()}>
|
||||
<a class="inline-block font-bold text-xl" href={getHomePermalink(currentLang)}>
|
||||
{SITE?.name}
|
||||
</a>
|
||||
|
||||
<!-- Terms & Privacy Policy Links -->
|
||||
<div class="flex items-center space-x-4 text-sm text-muted">
|
||||
|
||||
{secondaryLinks.map(({ text, href }) => (
|
||||
<a class="hover:text-gray-700 dark:hover:text-gray-200 transition duration-150 ease-in-out" href={href}>
|
||||
{text}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@@ -8,6 +8,7 @@ import LanguageDropdown from '~/components/LanguageDropdown.astro';
|
||||
|
||||
import { getHomePermalink } from '~/utils/permalinks';
|
||||
import { trimSlash, getAsset } from '~/utils/permalinks';
|
||||
import { getHeaderData } from '~/navigation';
|
||||
|
||||
interface Link {
|
||||
text?: string;
|
||||
@@ -18,6 +19,7 @@ interface Link {
|
||||
|
||||
interface MenuLink extends Link {
|
||||
links?: Array<MenuLink>;
|
||||
isHashLink?: boolean;
|
||||
}
|
||||
|
||||
export interface Props {
|
||||
@@ -31,9 +33,42 @@ export interface Props {
|
||||
position?: string;
|
||||
}
|
||||
|
||||
import { supportedLanguages } from '~/i18n/translations';
|
||||
|
||||
// Get current language from URL
|
||||
const currentPath = `/${trimSlash(new URL(Astro.url).pathname)}`;
|
||||
const pathSegments = currentPath.split('/').filter(Boolean);
|
||||
|
||||
// Define the type for supported languages
|
||||
type SupportedLanguage = typeof supportedLanguages[number];
|
||||
|
||||
// Check for language in URL path
|
||||
let currentLang = pathSegments[0] && supportedLanguages.includes(pathSegments[0] as SupportedLanguage)
|
||||
? pathSegments[0] as SupportedLanguage
|
||||
: null;
|
||||
|
||||
// If no language in URL, check cookies
|
||||
if (!currentLang) {
|
||||
const cookies = Astro.request.headers.get('cookie') || '';
|
||||
const cookieLanguage = cookies.split(';')
|
||||
.map(cookie => cookie.trim())
|
||||
.find(cookie => cookie.startsWith('preferredLanguage='))
|
||||
?.split('=')[1];
|
||||
|
||||
if (cookieLanguage && supportedLanguages.includes(cookieLanguage as SupportedLanguage)) {
|
||||
currentLang = cookieLanguage as SupportedLanguage;
|
||||
} else {
|
||||
// Default to English if no language is found
|
||||
currentLang = 'en';
|
||||
}
|
||||
}
|
||||
|
||||
// Get translated header data
|
||||
const headerData = getHeaderData(currentLang);
|
||||
|
||||
const {
|
||||
id = 'header',
|
||||
links = [],
|
||||
links = headerData.links,
|
||||
isSticky = false,
|
||||
isDark = false,
|
||||
isFullWidth = false,
|
||||
@@ -41,8 +76,6 @@ const {
|
||||
showRssFeed = false,
|
||||
position = 'center',
|
||||
} = Astro.props;
|
||||
|
||||
const currentPath = `/${trimSlash(new URL(Astro.url).pathname)}`;
|
||||
---
|
||||
|
||||
<header
|
||||
@@ -107,7 +140,7 @@ const currentPath = `/${trimSlash(new URL(Astro.url).pathname)}`;
|
||||
<Icon name="tabler:chevron-down" class="w-3.5 h-3.5 ml-0.5 rtl:ml-0 rtl:mr-0.5 hidden md:inline" />
|
||||
</button>
|
||||
<ul class="dropdown-menu md:backdrop-blur-md dark:md:bg-dark rounded md:absolute pl-4 md:pl-0 md:hidden font-medium md:bg-white/90 md:min-w-[200px] drop-shadow-xl">
|
||||
{links.map(({ text: text2, href: href2 }) => (
|
||||
{links.map(({ text: text2, href: href2, isHashLink }) => (
|
||||
<li>
|
||||
<a
|
||||
class:list={[
|
||||
@@ -115,6 +148,7 @@ const currentPath = `/${trimSlash(new URL(Astro.url).pathname)}`;
|
||||
{ 'aw-link-active': href2 === currentPath },
|
||||
]}
|
||||
href={href2}
|
||||
data-hash-link={isHashLink ? 'true' : undefined}
|
||||
>
|
||||
{text2}
|
||||
</a>
|
||||
@@ -129,6 +163,7 @@ const currentPath = `/${trimSlash(new URL(Astro.url).pathname)}`;
|
||||
{ 'aw-link-active': href === currentPath },
|
||||
]}
|
||||
href={href}
|
||||
data-hash-link={href?.includes('#') ? 'true' : undefined}
|
||||
>
|
||||
{text}
|
||||
</a>
|
||||
|
Reference in New Issue
Block a user