1

I'm trying to enable language selection in Next.js via a dropdown menu. If the links aren't nested inside the select tag, they're working fine. As soon as they are though, they're not responding anymore. I'm assuming this is because of a missing event handler and I think that the solution could be rather simple, but I just can't get it to work.

Would be great if someone could have a look at this. Also I'm not looking for a solution to just switch between two languages via a ternary operator, as I'd like to use the logic for future projects with more than two languages. It is also important for me to stick to the select tag, as this makes the most sense for a selection of languages and provides better accessibility.

This is working ✅

{router.locales.map((language) => (
  <Link
    href={router.asPath}
    locale={language}
    scroll={false}
    key={language}
  >
  <button type='button'>
    {language === 'en' ? 'EN' : language === 'de' ? 'DE' : null}
  </button>
  </Link>
))}

This is not working ❌

<select name='languages' id='language-select'>
  {router.locales.map((language) => (
    <Link
      href={router.asPath}
      locale={language}
      scroll={false}
      key={language}
    >
      <option value={language}>
        {language === 'en'
          ? 'EN'
          : language === 'de'
          ? 'DE'
          : null}
      </option>
    </Link>
  ))}
</select>

Thank you very much in advance for taking the time to read this and trying to help me, I really appreciate it!

juliomalves
  • 42,130
  • 20
  • 150
  • 146
stevefrenzel
  • 25
  • 1
  • 5

1 Answers1

3

If you absolutely need to stick with select, rather than relying on next/link you should listen to the select's onChange event and trigger a route change with next/router instead.

const SomePage = () => {
    const router = useRouter()

    const onSelectChange = (e) => {
        const locale = e.target.value;
        router.push(router.asPath, router.asPath, {
            locale,
            scroll: false 
        })
    }

    return (
        // ...
        <select name="languages" id="language-select" onChange={onSelectChange}>
            {router.locales.map((language) => (
                <option value={language}>
                    {language === "en" ? "EN" : language === "de" ? "DE" : null}
                </option>
            ))}
        </select>
        // ...
    )
}
juliomalves
  • 42,130
  • 20
  • 150
  • 146