Next.js Discord

Discord Forum

Access alternates urls in component

Unanswered
Asari posted this in #help-forum
Open in Discord
AsariOP
Is there a way to access alternate urls in a component that are created by the generateMetadata function?

I'm using the following function in my page.tsx to generate the alternate urls.

export async function generateMetadata({params}: {params: {lang: string, slug: string}}): Promise<Metadata> {
  const post = await getCachedClient()<SanityDocument>(postQuery, { slug: params.slug, language: params.lang });

  if (!post) {
    return {}
  }

  const languages = {};
  post._translations.forEach((translation) => {
    languages[`${translation.language}`] = `${translation.language}/${translation.slug.current}`;
  });

  return {
    metadataBase: new URL(`${process.env.NEXT_PUBLIC_SITE_URL!}`),
    alternates: {
      canonical: `/${params.lang}/${params.slug}`,
      languages
    }
  }

}


I would love to use those urls in my LocaleSwitcher component. So I can redirect to the correct translated alternative.

1 Reply

AsariOP
This is my current solutions, don't know if this is the way to go

import { useEffect, useState } from 'react';
import { i18n } from '@/languages'
import { usePathname } from 'next/navigation';
import Link from 'next/link';

export default function LanguageSelector() {
  const [links, setLinks] = useState([]);

  const pathName = usePathname();

  useEffect(() => {
    const linkElements = document.querySelectorAll('head link[rel="alternate"]');
    const linkList = Array.from(linkElements).map((link) => ({
      href: link.href,
      title: link.title,
    }));
    setLinks(linkList);
  }, []);

  return (
    <div>
      <p>Locale switcher:</p>
      <ul className='flex space-x-4'>
        {i18n.languages.map((locale) => {
          const link = links.find((l) => l.href.includes(`/${locale.id}/`));
          const href = link ? link.href : `/${locale.id}/`;
          return (
            <li key={locale.id}>
              <Link href={href}>{locale.title}</Link>
            </li>
          );
        })}
      </ul>
    </div>
  );
}