feat: implement locale-aware routing with [locale] dynamic segments
Some checks failed
Build and Deploy / build (push) Has been cancelled
Some checks failed
Build and Deploy / build (push) Has been cancelled
WARNING: This change breaks existing SEO URLs for Serbian locale. Changes: - Migrated from separate locale folders (src/app/en/, src/app/de/, etc.) to [locale] dynamic segments (src/app/[locale]/) - Serbian is now at /sr/ instead of / (root) - English at /en/, German at /de/, French at /fr/ - All components updated to generate locale-aware links - Root / now redirects to /sr (307 temporary redirect) SEO Impact: - Previously indexed Serbian URLs (/, /products, /about, /contact) will now return 404 or redirect to /sr/* URLs - This is a breaking change for SEO - Serbian pages should ideally remain at root (/) with only non-default locales getting prefix - Consider implementing 301 redirects from old URLs to maintain search engine rankings Technical Notes: - next-intl v4 with [locale] structure requires ALL locales to have the prefix (cannot have default locale at root) - Alternative approach would be separate folder structure per locale
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { motion } from "framer-motion";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
const mediaLogos = [
|
||||
{ name: "VOGUE", style: "serif" },
|
||||
@@ -15,10 +16,10 @@ const mediaLogos = [
|
||||
|
||||
function LogoItem({ name }: { name: string }) {
|
||||
const isSerif = name === "VOGUE" || name === "ELLE" || name === "COSMOPOLITAN" || name === "Bazaar" || name === "GLAMOUR";
|
||||
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-center px-10 py-4 grayscale opacity-40 hover:grayscale-0 hover:opacity-100 transition-all duration-500 flex-shrink-0">
|
||||
<span
|
||||
<span
|
||||
className={`
|
||||
text-xl md:text-2xl tracking-[0.15em] text-white font-bold
|
||||
${isSerif ? 'font-serif italic' : 'font-sans uppercase'}
|
||||
@@ -34,6 +35,8 @@ function LogoItem({ name }: { name: string }) {
|
||||
}
|
||||
|
||||
export default function AsSeenIn() {
|
||||
const t = useTranslations("AsSeenIn");
|
||||
|
||||
return (
|
||||
<section className="py-12 bg-[#1a1a1a] overflow-hidden border-y border-white/10">
|
||||
<div className="container mx-auto px-4 mb-8">
|
||||
@@ -44,19 +47,14 @@ export default function AsSeenIn() {
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.6 }}
|
||||
>
|
||||
As Featured In
|
||||
{t("title")}
|
||||
</motion.p>
|
||||
</div>
|
||||
|
||||
{/* Scrolling Marquee */}
|
||||
<div className="relative">
|
||||
{/* Left gradient fade */}
|
||||
<div className="absolute left-0 top-0 bottom-0 w-32 bg-gradient-to-r from-[#1a1a1a] to-transparent z-10 pointer-events-none" />
|
||||
|
||||
{/* Right gradient fade */}
|
||||
<div className="absolute right-0 top-0 bottom-0 w-32 bg-gradient-to-l from-[#1a1a1a] to-transparent z-10 pointer-events-none" />
|
||||
|
||||
{/* Marquee container */}
|
||||
|
||||
<div className="flex overflow-hidden">
|
||||
<motion.div
|
||||
className="flex items-center gap-16"
|
||||
@@ -72,11 +70,9 @@ export default function AsSeenIn() {
|
||||
},
|
||||
}}
|
||||
>
|
||||
{/* First set of logos */}
|
||||
{mediaLogos.map((logo, index) => (
|
||||
<LogoItem key={`first-${index}`} name={logo.name} />
|
||||
))}
|
||||
{/* Duplicate for seamless loop */}
|
||||
{mediaLogos.map((logo, index) => (
|
||||
<LogoItem key={`second-${index}`} name={logo.name} />
|
||||
))}
|
||||
@@ -85,4 +81,4 @@ export default function AsSeenIn() {
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user