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

Support namespaces per project in monorepo #890

Open
RobHannay opened this issue Aug 16, 2023 · 2 comments
Open

Support namespaces per project in monorepo #890

RobHannay opened this issue Aug 16, 2023 · 2 comments

Comments

@RobHannay
Copy link
Contributor

RobHannay commented Aug 16, 2023

🚀 Feature Proposal

True namespace detection through static function call analysis, or through allowing easy project-specific config.

See example below for what I would like to achieve.

Either adding functionality to detect the namespace specified in the 'wrapping' hook, or allow some config to be added to specify that the hook being used in any given package has a certain default namespace, other than the usual config.

Motivation

Please outline the motivation for the proposal.

I have multiple projects in a monorepo, which use their own namespace to split translations, but share a common one too. They also import from each other.

app/
├─ packages/
│  ├─ component-library/
│  ├─ admin/
│  ├─ webapp/
├─ locales/
│  ├─ en/
│  │  ├─ common.json
│  │  ├─ component-library.json
│  │  ├─ admin.json
│  │  ├─ webapp.json

I want to avoid duplication and enforce consistency by providing a useTranslation hook per project.

Example

// webapp/useTranslation.ts

import { useTranslation as useTranslation1 } from 'react-i18next';

export const useTranslation = (options?: Parameters<typeof useTranslation1>[1]) =>
  useTranslation1(['webapp', 'common'], options);

Some component-library component

// component-library/CoreComponent.tsx

import useTranslation from 'component-library/useTranslation';

export function CoreComponent() {
  const { t } = useTranslation();

  return <div>{t('Some.comp-lib.key')}</div>;
}

And in some app component:

// webapp/component

import useTranslation from 'webapp/useTranslation';

export function CoreComponent() {
  const { t } = useTranslation();

  // Note that using the a namespace prefix does still work, whether `webapp:` or `common:` or anything else.
 
  return <div>
    {t('Some.webapp.key')}
    {t('common:Dates.year')}
  </div>;
}

This all works correctly, and helps us enforce using the correct namespace in each part of the app.

However, the parser is not aware that they are using the namespaces used within the project-specific useTranslation hooks.

Is this something that would even be feasible with how the parser works currently?

Workaround

My idea for a workaround would just be to customise the config for every package, and specify a different default namespace.

For example,

// i18next.admin.config.js 
module.exports = {
  ...
  input: ['admin/**/*'],
  defaultNamespace: 'admin',
};

and then run that script multiple times: i18next -c i18next.admin.config.js && i18next -c i18next.webapp.config.js &&...

@karellm
Copy link
Member

karellm commented Aug 18, 2023

Is there a reason you don't simply use the namespace everywhere? It would be more verbose but consistent and should work with the parser.

@RobHannay
Copy link
Contributor Author

Yeah this was a conscious decision to avoid doing useTranslation('key', 'admin') everywhere, but if you think that's just the most sensible path then we will have another think. But there is something nice about it being both automatic (using IDE imports) and lintable (enforce that only useAdminTranslation is import within the admin package, etc)

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

No branches or pull requests

2 participants