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

How to handle i18n ? #142

Open
ziadsarour opened this issue Jun 11, 2024 · 1 comment
Open

How to handle i18n ? #142

ziadsarour opened this issue Jun 11, 2024 · 1 comment

Comments

@ziadsarour
Copy link

ziadsarour commented Jun 11, 2024

Hi and thank you for this plugin !

I have an i18n website using @nuxtjs/i18n with a dropdown to switch locale.
It's working fine on my website
Inside my PWA, if I switch the locale manually and navigate through the app, it's working great.
But whenever I close the app, I'm falling back to the default locale.

Here is my nuxt.config.ts

  i18n: {
    baseUrl: process.env.WEBSITE_URL,
    strategy: 'prefix_and_default',
    customRoutes: 'config',
    trailingSlash: false,
    lazy: true,
    skipSettingLocaleOnNavigate: false,
    debug: false,
    detectBrowserLanguage: {
      useCookie: true,
      cookieKey: 'swany.i18n',
      redirectOn: 'root',
    },
  },
  pwa: {
    strategies: 'generateSW',
    registerType: 'autoUpdate',
    devOptions: {
      enabled: mode !== 'production',
      type: 'module',
      navigateFallback: '/',
      suppressWarnings: true,
    },
    workbox: {
      navigateFallback: '/',
    },
    pwaAssets: {
      disabled: false,
      config: true,
    },
    manifest: {
      lang: 'en',
      name: 'name',
      short_name: 'name',
      description: 'description',
      id: '/blog',
      start_url: '/blog',
      scope: '/',
      display: 'standalone',
      orientation: 'portrait',
      background_color: '#FFF',
      theme_color: '#FFF',
      prefer_related_applications: true,
    },
  },

It think it's because start_url is pointing to the default locale, so I will always be opening my PWA using the default locale.
I've seen someone suggesting localized webmanifests generation #52, would be great but once the PWA is installed it will not be possible to switch the locale because start_url is static.

I am thinking about checking at startup if I'm inside the PWA, if yes, redirect to the correct localized route using useI18n().locale.

But :

  1. I don't know how to check if I'm inside a PWA
  2. I'm not sure if the useI18n().locale will be set to the default locale before my check because of skipSettingLocaleOnNavigate: false

My questions :

  1. Should I use $pwa.isPWAInstalled or it is just a flag to know if I have the PWA installed on my device ?
  2. If useI18n().locale is not correct I will have to persist the user locale manually, how can I do this with a PWA ?
@ziadsarour
Copy link
Author

After reviewing the code, I know $pwa.isPWAInstalled means "I'm inside a PWA" based on

const ua = navigator.userAgent
const ios = ua.match(/iPhone|iPad|iPod/)
const useDisplay = display === 'standalone' || display === 'minimal-ui' ? `${display}` : 'standalone'
const standalone = window.matchMedia(`(display-mode: ${useDisplay})`).matches
const isInstalled = ref(!!(standalone || (ios && !ua.match(/Safari/))))
const isPWAInstalled = ref(isInstalled.value)
window.matchMedia(`(display-mode: ${useDisplay})`).addEventListener('change', (e) => {
// PWA on fullscreen mode will not match standalone nor minimal-ui
if (!isPWAInstalled.value && e.matches)
isPWAInstalled.value = true
})


I also have a local module which generate manifests based on the one generated by this plugin :

  • /manifest.webmanifest
  • /en/manifest.webmanifest
  • /fr/manifest.webmanifest
  • /{localeCode}/manifest.webmanifest

This local module is specific to my website but here is a snippet you could be inspired of :

...
  const directory = path.join(__dirname, '..', '.output', 'public');
  const baseManifest = getBaseManifest({ directory });

  for (const locale of locales) {
    saveManifest({
      directory,
      locale: locale.code,
      manifest: {
        ...baseManifest,
        description: t.description[locale.code] || baseManifest.description,
        start_url: locale.url,
      },
    });
  }
...

function getBaseManifest(options: {
  directory: string;
}) {
  const filepath = path.join(options.directory, 'manifest.webmanifest');
  const file = fs.readFileSync(filepath, { encoding: 'utf-8' });

  if (!file) {
    throw `module webmanifests: missing base manifest file`;
  }

  return JSON.parse(file);
}

function saveManifest(options: {
  directory: string;
  locale: RegionLocale['code'];
  manifest: any;
}) {
  const filepath = path.join(options.directory, options.locale, 'manifest.webmanifest');
  fs.writeFileSync(filepath, JSON.stringify(options.manifest), { encoding: 'utf-8' });
}

Be sure to remove your / and to manually set the correct head href manifest based on the user locale.


I now need to resolve 2.

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

1 participant