angeloocana / gatsby-plugin-i18n

Multi language routes for Gatsby
435 stars 77 forks source link

Default language as / #27

Open HriBB opened 6 years ago

HriBB commented 6 years ago

Hi

Is it possible to use some language as default, and prefix other languages with two letter string? For example Slovenian would be the default

/
/novice/
/o-nas/

And English would be an alternative

/en/
/en/news/
/en/about/

Thanks

sedubois commented 6 years ago

I recently wondered the same, this would be quite useful. Currently there's no easy way to link to any page, specific redirect logic needs to be added. For example if I have an /en/about and /fr/about page, linking to /about won't work. If pages in the default language have no prefix, it would solve this issue.

HriBB commented 6 years ago

What about /si/novice and /en/news? This patterns is also not supported, right?

I was thinking a lot about i18n in the last few days. There are so many different scenarios and requirements, that it would be virtually impossible to cover all of them.

My idea is, to simply inject i18n functions into all my Gatsby pages. I could handle language in my layout or page components, or inject it into the context in onCreatePage and onCreateNode, or add a field using createNodeField. Maybe provide a centralized function, something like getLanguageFromPath, that would determine the current language. Anyway, I am fairly new on Gatsby, still need to learn a lot of stuff ...

Currently, this plugin does not cover my requirements.

sedubois commented 6 years ago

@HriBB plugin does not cover my requirements either, but was a good start. Would be great to improve it little by little so that we don't all have to redo the same work.

I'd also like to try out js-lingui which looks promising (currently using react-intl).

braco commented 6 years ago

Ideal scenario for me:

  1. Default language needs no prefix
  2. Translations kept in a key/value dictionary, no duplicate layouts
  3. Pre-rendered routes, no fetching afterwards

We're not that far from these goals with this package, are we?

sedubois commented 6 years ago

It seems so. Would be great to have @angeloocana’s inputs on what would need to be done to get there.

braco commented 6 years ago

One more consideration would be using rel=canonical on the default language if there is duplication between, say, /foo and /en/foo

@angeloocana, if you could chime in, I have a window of time to submit some PRs this week.

angeloocana commented 6 years ago

Hello guys! Awesome discussion!!!

We need a way to map and link the translations pages. Let's think about how should the API looks like.

Ideas:

- Params in the header of the markdown.
```md
---
slug: '/news'
translations:
  pt: '/noticias'
---

What do you guys think?

HriBB commented 6 years ago

I decided to try to build my own solution, just to learn Gatsby. In the end I decided to query translations with graphql. Feels like the right way with Gatsby.

Here's a gist of what I came up with https://gist.github.com/HriBB/1fca4773651948741311a2ccda76d491

I need to add two things in my page component:

  1. query the locale with graphql
  2. enhance Page component with a custom translate HOC

This HOC wraps react-i18next translate function, and also loads resources using addResources.

import React, { Component, Fragment } from 'react'
import Link from 'gatsby-link'
import { translate } from 'utils/i18n'
import About from 'components/About'

class AboutPage extends Component {
  componentWillMount() {
    this.props.setHeader('transparent')
  }
  render() {
    return (
      <About {...this.props} />
    )
  }
}

export default translate('About')(AboutPage)

export const query = graphql`
  query About($lng: String!) {
    locales: allLocale(filter: { lng: { eq: $lng }, ns: { eq: "About" } }) {
      ...LocaleFragment
    }
    laboratoryImage: imageSharp(id: { regex: "/photos/laboratory.jpg/" }) {
      sizes(maxWidth: 1920 ) {
        ...GatsbyImageSharpSizes
      }
    }
  }
`;

@angeloocana I will write some more thoughts and ideas in the following days.

AAverin commented 6 years ago

There should be a way to have a fallback So if I have

index.js -> english version
index.ru.js -> russian version

When opening <base>/en/index I should fall back to index.js because there is no specific english version provided

This would solve having the same content for many languages and still support different language routes

As for the specialized naming of urls for other languages – I would keep it as separate feature and PR

ThiagoMiranda commented 6 years ago

@HriBB Hi I've tried your gist code but my onCreateNode callback is failing on this part:

  if (
    node.internal.type === `MarkdownRemark` &&
        typeof node.slug === `undefined`
  ) {
    const { fields: { lng, slug, type } } = getNode(node.parent)
    createNodeField({ node, name: `lng`, value: lng })
    createNodeField({ node, name: `slug`, value: slug })
    createNodeField({ node, name: `type`, value: type })
  }

with the following error: TypeError: Cannot destructure propertylngof 'undefined' or 'null'. Do you have any idea of what it is? The funny thing is that this only occurs in the first build. After the .cache directory is generated, it won't fail anymore.

Btw, do you have a working repository of that own i18n extension? That would help a lot

Thanks!

ThiagoMiranda commented 6 years ago

Actually I've saw that the https://imagineclarity.com/ site ( that is pointed as an example of the gatsby-plugin-i18n use ) doesn't show the default language just when you switch to french. But there's no source of the page. Can anyone help? Thanks

sedubois commented 6 years ago

@thiagomiranda Imagine Clarity has been switched back to another technology for now, it’s not React any more (hope to get back to this later).

CanRau commented 6 years ago

Hey guys i'm a little confused about language urls Anyone knows if it's beneficial to have prefixes for all languages, so for default too) google wrote in some article prefixes should be on every page but didn't get into more detail about it I'm used to default being just / and it looks kind of cleaner but maybe it's clearer when every language has it's prefix (like currently in the plugin)

Mentioned article Quote: Put the content of every language in a different subdirectory. This is easier to handle when updating and maintaining your site. For our example, you would have example.com/en/, example.com/de/, and example.com/es/.

Or is it just for maintenance sake?

angeloocana commented 6 years ago

Hi @CanRau

I think using prefixes for all languages makes it easier to build and change to another language.

But I do think the main language using just '/' is good for the users.

CanRau commented 6 years ago

but it wouldn't really affect seo, or would it? i'm using a custom i18n solution at the moment so i already have prefixes only on the non default language and as titles are translated, too it's not only changing the prefix to switch languages