Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support layer locales and pages #1925

Merged
merged 9 commits into from
Mar 24, 2023

Conversation

BobbieGoede
Copy link
Collaborator

@BobbieGoede BobbieGoede commented Mar 11, 2023

πŸ”— Linked issue

#1890
#1837
#1743

❓ Type of change

  • πŸ“– Documentation (updates to the documentation or readme)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • πŸ‘Œ Enhancement (improving an existing functionality like performance)
  • ✨ New feature (a non-breaking change that adds functionality)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

πŸ“š Description

This PR implements the workaround as described in this comment. But I have added basic support for layer pages and routes as well.

Unfortunately it seems like there are issues with the current extends behavior when using a git repository as a layer. So when trying to use pages from a git repository layer, an error similar to nuxt/nuxt#18448 gets thrown. Locales from such layers do seem to work with this implementation.

The resulting behavior when merging (lazy-loaded) locales

// project layer i18n
{
  langDir: 'lang',
  locales: [{ code: 'fr', file: 'fr.json'}],
}

// shared layer i18n
{
  langDir: 'lang', // layers/shared-i18n/lang
  locales: [{ code: 'fr', file: 'fr.json'}],
}

// transformed result by module
{
  langDir: 'lang',
  locales: [{
    code: 'fr', 
    files: [
      '../layers/shared-i18n/lang/fr.json',
      'fr.json',
    ], 
  }],
}

I have added basic tests and documentation, these can be expanded if needed.

πŸ“ Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

@memic84
Copy link

memic84 commented Mar 11, 2023

This is great! Only thing that i have some doubts about is that the layers/extend functionality is a Nuxt default feature, and it actually does all the work before anything is loaded. Shouldn't nuxt-i18n work with the merged app, with the final result of the app and the extended layer, so that you shouldn't have any extra options for enabling or disabled it here.

If someone is using the layers, and uses pages which are extended, i think that you can make the assumption that he want the files that is used, to be used the same way, as if it wasn't extended (if this makes any sense).

@kazupon
Copy link
Collaborator

kazupon commented Mar 12, 2023

Thank you for your PR!
This is awesome! πŸ’―

I have checked your logic, so it looks good to me.
I hope you can do the next step, testing and adding documentation!

@ineshbose
Copy link
Collaborator

Love this! Would be great if @ memic84's gets addressed too πŸ˜„

@BobbieGoede
Copy link
Collaborator Author

@memic84 & @ineshbose I agree that ideally it should fully work when extending, and I actually prefer having no option to disable it.

The reason for adding those options is because I ran into issues trying to build a project when extending using layers from a remote source, with some bad troubleshooting I thought my changes were the cause of those issues, but it turns out this happens in a clean project as well. πŸ˜… I have opened an issue there nuxt/nuxt#19613.

So the ability to disable these features will be removed unless we run into a real use case for it. Hope that resolves the doubts you described!

While nuxt/nuxt#19613 does prevent building when extending using remote layers, it seems to work fine with local layers, I will make sure to mention it when adding the documentation.

@memic84
Copy link

memic84 commented Mar 12, 2023

Yeah now it makes sense with the explanation, thanks! Let me know if i can help. I'll test it in my project asap.

@BobbieGoede
Copy link
Collaborator Author

Should there be any logic to merging locales if they have domains? I'm probably overthinking it but here are some examples with different merging strategies:

Scenario 1

// project
// `differentDomains` is set to false
extends: ['layer1', 'layer2'],
i18n: {
  differentDomains: false,
  locales: [
    { code: 'en', file: 'en.json' }
    { code: 'fr', file: 'fr.json' }
  ],
}
// layer 1
locales: [
  { code: 'en', file: 'en.json', domain: 'mydomain.com' }
]

// layer 2
locales: [
  { code: 'en', file: 'en.json', domain: 'otherdomain.com' }
]
// result 1-1
// matching locale `code` have their files merged
locales: [
  { code: 'en', files: ['[layer2-path]/en.json', '[layer1-path]/en.json', 'en.json'] },
  { code: 'fr', files: ['fr.json'] }
]

// result 1-2
// locale `domain` do not match, do not merge
locales: [
  { code: 'en', files: ['en.json'] },
  { code: 'fr', files: ['fr.json'] }
]

// result 1-3
// merge locale options, ignoring differing options and merging based on `code`
// keeping in mind that earlier layers have higher priority (`domain` value is that of layer1)
locales: [
  { code: 'en', files: ['[layer2-path]/en.json', '[layer1-path]/en.json', 'en.json'], domain: 'mydomain.com',  },
  { code: 'fr', files: ['fr.json'] }
]

Scenario 2

// project
// `differentDomains` is set to true, implying the consuming project cares about domain settings
extends: ['layer1', 'layer2'],
i18n: {
  differentDomains: true,
  locales: [
    { code: 'en', file: 'en.json', domain: 'mydomain.com' }
  ],
}
// layer 1
locales: [
  { code: 'en', file: 'en.json', domain: 'mydomain.com' },
  { code: 'fr', file: 'fr.json', domain: 'mydomain.fr' }
]

// layer 2
locales: [
  { code: 'en', file: 'en.json', domain: 'otherdomain.com' },
  { code: 'fr', file: 'fr.json', domain: 'otherdomain.fr' }
]
// result 2-1
// `domain` matching project are merged, first found locales are added, others are omitted
locales: [
  { code: 'en', files: ['[layer1-path]/en.json', 'en.json'], domain: 'mydomain.com' },
  { code: 'fr', files: ['[layer1-path]/fr.json'], domain: 'mydomain.fr' }
]

// result 2-2
// merge options regardless of domain, more translations are better
// keeping in mind that earlier layers have higher priority
locales: [
  { code: 'en', files: ['[layer2-path]/en.json', '[layer1-path]/en.json', 'en.json'], domain: 'mydomain.com'  },
  { code: 'fr', files: ['[layer2-path]/fr.json', '[layer1-path]/fr.json'], domain: 'mydomain.fr' }
]

@BobbieGoede BobbieGoede force-pushed the feat/layers-locales branch 3 times, most recently from 11cd655 to c1c8b7a Compare March 16, 2023 09:08
Copy link
Collaborator

kazupon commented Mar 20, 2023

Thanks again for your contribution.
Sorry my late reply.

I honestly, I don't know about locale merging for domain cases, because there is no best practice with layers yet nuxt official πŸ˜…
For the locale messages, I think that is good to use files.

@memic84
Copy link

memic84 commented Mar 22, 2023

Is this going to be in the next release?

@kazupon
Copy link
Collaborator

kazupon commented Mar 23, 2023

@BobbieGoede
Hi!
Could you resolve the conflict, please? πŸ™
I've merge this big PR πŸ˜…

@kazupon
Copy link
Collaborator

kazupon commented Mar 23, 2023

Is this going to be in the next release?

I think we need to prepare the docs about nuxt layers

@BobbieGoede
Copy link
Collaborator Author

@kazupon Sure!

@memic84 @kazupon I was still working on an issue that shows up after building a project using this implementation, it seems like SSR doesn't have access to the merged locales. I will rebase this branch and add my latest changes today, perhaps you can see what the cause is faster than me πŸ˜…

@BobbieGoede
Copy link
Collaborator Author

@kazupon I have resolved the conflicts and added a very basic test to demonstrate the current issue, the translation for the key hello works in dev mode, but only works client-side when running the built project.

At first I thought this might be related to the paths that were set in the generated i18n.options.mjs file, so I made changes to make sure those paths were correct but it made no difference. It looks like recent changes have removed the paths key from the generated options so that rules that out πŸ˜…

@BobbieGoede
Copy link
Collaborator Author

It looks like the way locale files were being handled in bundler.ts had to be changed, it seems to be working as expected in both dev mode and after building now. I'll be adding documentation later, hopefully today. The test for this functionality is a bit basic, if there are any specific cases that should be tested let me know!

@BobbieGoede
Copy link
Collaborator Author

@kazupon I have added a page to the docs that briefly describes the functionality and added a few more tests.

@BobbieGoede BobbieGoede marked this pull request as ready for review March 24, 2023 15:41
@kazupon
Copy link
Collaborator

kazupon commented Mar 24, 2023

@BobbieGoede
Thank you very much!
Awesome!
LGTM!

@kazupon kazupon merged commit f36673e into nuxt-modules:next Mar 24, 2023
@memic84
Copy link

memic84 commented Mar 30, 2023

Thank you both!!

I have one question however, see: https://v8.i18n.nuxtjs.org/guide/layers#pages-routing

If you have pages in the layer, which is included in your project, that one doesn't seem to get merged together. I have both lazy and langDir in both configs.

A reproduction: https://stackblitz.com/edit/nuxt-starter-5ar22s?file=nuxt.config.ts,base%2Fnuxt.config.ts,base%2Froutes%2FRoutes.js,package.json

See also for more information: #1837

Could be that i am doing something wrong here.

@BobbieGoede
Copy link
Collaborator Author

@memic84 the latest beta (v8.0.0-beta.10) does not yet include this feature, you can try it out by installing the edge version of the module.

Let me know if it works after installing the edge version like this npm i -D @nuxtjs/i18n@npm:@nuxtjs/i18n-edge.

@memic84
Copy link

memic84 commented Mar 30, 2023

@BobbieGoede I have tried the edge version, and this is what i get.

Reproduction
https://stackblitz.com/edit/nuxt-starter-5ar22s?file=nuxt.config.ts,package.json

The same warning as before, that the route cannot be found:

[@nuxtjs/i18n]: Couldn't find AnalizedNuxtPageMeta by NuxtPage (/login), so no custom route for it

Folder base is the extend folder, and there i have one page login.vue, where in the root config i set the pages key of i18n, to name it 'aanmelden'.

Do you have a playground or stackbilitz example where this works, so that i can see what i am doing wrong here?

@BobbieGoede
Copy link
Collaborator Author

BobbieGoede commented Mar 30, 2023

@memic84 Can you check if you're experiencing the same issue in this fork of your reproduction? https://stackblitz.com/edit/nuxt-starter-jrk2ex?file=nuxt.config.ts

@memic84
Copy link

memic84 commented Mar 30, 2023

It works now in both versions. What did you change in the latest in next version?

The problem seem to be the following, it seemed that for the routes which were used as children, such as /pages/parent and then parent/child-1.vue, i got that message. I reworked the code a bit, to use a wrapper component instead of route children, and it worked.

[@nuxtjs/i18n]: Couldn't find AnalizedNuxtPageMeta by NuxtPage (ROUTE NAME), so no custom route for it

However i do get other issues in the edge versions, but those are not related to this pull request.

Thank you for the solution!

DarthGigi pushed a commit to DarthGigi/i18n that referenced this pull request Apr 16, 2024
* feat: support layer locales and pages

* fix: locales not merged when lazy is false

* test: add basic layers test

* fix: layer locales not being bundled correctly

* docs: add layers page

* feat: change playground to illustrate layer override behavior

* test: add additional layer tests

* refactor: restructure layers implementation

* fix: update lockfile
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants