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

Vercel: Unable to load translations using getServerSideProps/loadTranslations #49

Open
atanaskanchev opened this issue Jan 9, 2022 · 10 comments
Labels
bug Something isn't working good first issue Good for newcomers

Comments

@atanaskanchev
Copy link

While the setup works fine running locally, the deployed to vercel app returns empty translations by loadTranslations in getServerSideProps

GET | https://app.vercel.app/_next/data/HZ7wajlS0AuNQGjuW_9so/en/app/dashboard.json

{"pageProps":{"__ni18n_server__":{"resources":{"en":{"dashboard":{},"common":{}}},"ns":["dashboard","common"]}},"__N_SSP":true}

ni18n.config.ts

import ChainedBackend from 'i18next-chained-backend'
import HttpBackend from 'i18next-http-backend'
import LocalStorageBackend from 'i18next-localstorage-backend'

const isBrowser = typeof window !== 'undefined'

const isRunningOnLocalhost = !!process.env['NEXT_PUBLIC_IS_RUNNING_ON_LOCALHOST']

const localePath = '{{lng}}/{{ns}}.json'

export const ni18nConfig = {
  supportedLngs: ['en'],
  ns: ['common', 'auth', 'dashboard'],
  use: isBrowser ? [ChainedBackend] : undefined,
  defaultNS: 'common',
  fallbackLng: 'en',

  backend: isBrowser
    ? {
        backends: [LocalStorageBackend, HttpBackend],
        backendOptions: [{ expirationTime: 24 * 60 * 60 * 1000 }, { loadPath: `locales/${localePath}` }]
      }
    : isRunningOnLocalhost
    ? { loadPath: `apps/ui-web-app/public/locales/${localePath}` }
    : { loadPath: `locales/${localePath}` },

  interpolation: {
    format: (value, format, lng, options) => {
    ...
    }
  }
}

next.config.js

// eslint-disable-next-line @typescript-eslint/no-var-requires
const withNx = require('@nrwl/next/plugins/with-nx')

"i18next": "^21.6.5",
"i18next-chained-backend": "^3.0.2",
"i18next-http-backend": "^1.3.1",
"i18next-localstorage-backend": "^3.1.3",
"next": "12.0.7",
"ni18n": "^1.0.3-rc.0",


/**
 * @type {import('@nrwl/next/plugins/with-nx').WithNxOptions}
 **/

const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true'
})

const nextConfig = {
  nx: {
    // Set this to true if you would like to to use SVGR
    // See: https://github.com/gregberge/svgr
    svgr: false
  },
  images: {
    domains: ['cdn.nordigen.com']
  },
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'es']
  }
}

module.exports = withBundleAnalyzer(withNx(nextConfig))
const Dashboard: NextPage = () => (
  <AuthGuard>
    <RoutePermissionsGuard>
      <SubscriptionGuard>
        <DashboardLayout>
          <DashboardPage />
        </DashboardLayout>
      </SubscriptionGuard>
    </RoutePermissionsGuard>
  </AuthGuard>
)

export const getServerSideProps = async ({ locale }) => {
  const something = {
    ...(await loadTranslations(ni18nConfig, locale, ['dashboard']))
  }
  console.log('file: index.tsx ~ line 25 ~ getServerSideProps ~ something', JSON.stringify(something))

  return {
    props: something
  }
}

export default Dashboard
 {"i18next": "^21.6.5",
    "i18next-chained-backend": "^3.0.2",
    "i18next-http-backend": "^1.3.1",
    "i18next-localstorage-backend": "^3.1.3",
    "next": "12.0.7",
    "ni18n": "^1.0.3-rc.0"}

image

@JCQuintas
Copy link
Owner

Hi @atanaskanchev, if the prebuilt JSON is empty it probably means the issue is on the build step.

I would start looking at the path's configuration after the isRunningOnLocalhost conditional.
It is possible you don't need the conditional at all, can you try one of the following solutions?

  1. use undefined
  2. use { loadPath: `apps/ui-web-app/public/locales/${localePath}` }
  3. use { loadPath: `locales/${localePath}` }

If none of these work, would you mind creating a repository where with the reproducible behaviour where I can try to find a solution?

atanaskanchev added a commit to atanaskanchev/ni18n-nx-issue that referenced this issue Jan 9, 2022
@atanaskanchev
Copy link
Author

Hi @JCQuintas thanks for the quick response.

I've recreated the issue here https://github.com/atanaskanchev/ni18n-nx-issue and it's deployed to https://ni18n-nx-issue-9y6puo3xe-atanaskanchev.vercel.app/dashboard

localhost
image

vercel
image

vercel workspace
image

In the config, if !isRunningOnLocalhost I am setting the locales path { loadPath: locales/${localePath} } and it seems it matches the vercel workspace

 backend: isBrowser
    ? {
        backends: [LocalStorageBackend, HttpBackend],
        backendOptions: [
          { expirationTime: 24 * 60 * 60 * 1000 },
          { loadPath: `locales/${localePath}` },
        ],
      }
    : isRunningOnLocalhost
    ? { loadPath: `apps/ni18n-nx-issue/public/locales/${localePath}` }
    : { loadPath: `locales/${localePath}` },

@JCQuintas
Copy link
Owner

So it seems when deploying to vercel, we don't have access to the public folder from the getServerSideProps. :(

The current behaviour work if you are deploying using a docker container though... I've opened a bug issue on nextjs repo and will keep you posted.

A quick solution for your case right now would be to use getStaticProps instead for the time being, or use clientNamespaces to have the translations loaded on the client only.

@atanaskanchev atanaskanchev changed the title Nx Monorepo | Vercel : Unable to load translations using clientNamespaces Vercel: Unable to load translations using getServerSideProps/loadTranslations Jan 10, 2022
@JCQuintas JCQuintas added bug Something isn't working good first issue Good for newcomers labels Jan 11, 2022
@atanaskanchev
Copy link
Author

Hi @JCQuintas I've had a try with v1.0.4-rc.3 but it seems the issue with Vercel still persist.

@JCQuintas
Copy link
Owner

Indeed, it didn't work. Looking at it deeper, it seems that the issue is on the https://github.com/vercel/nft packager that doesn't allow a "third party module" to flag a file as "necessary" out of its scope. So at the moment we can't really fix that automatically without creating a patch to the nft package and then waiting for vercel to update it.

In the meantime, one workaround would be to create a function on your repository to do that for us

// force-locales-packing.js
import path from 'path'

export const forceLocalesPacking = () => path.join('./public/locales')

Then you should be able to run that inside your getServerSideProps and it will "tag" the files to be bundled. I intend on creating a documentation for this as well as soon as I have time. Then I try to work on a fix on the nft package itself.

Let me know if it works for you, else I can update the repo you linked above with the steps necessary to make it work.

@RodriguesCosta
Copy link

This worked for me.

import type { NamespacesNeeded, Ni18nOptions } from 'ni18n';
import { loadTranslations as ni18nLoadTranslations } from 'ni18n';
import path from 'path';

import { i18n } from '../../next.config';

export const namespaces = [
  'common',
  'register',
  'dashboard',
  'sidebar',
] as const;

export const ni18nConfig: Ni18nOptions = {
  supportedLngs: i18n?.locales,
  ns: namespaces,
};

export const loadTranslations = async (
  initialLocale?: string | undefined,
  namespacesNeeded?: NamespacesNeeded | undefined
) => {
  const locales = path.resolve('./', './public/locales');

  return await ni18nLoadTranslations(
    ni18nConfig,
    initialLocale,
    namespacesNeeded
  );
};

@zaniluca
Copy link

Has anyone found a solution to this?

@RodriguesCosta
Copy link

Has anyone found a solution to this?

This solved my problem #49 (comment)

const locales = path.resolve('./', './public/locales');

@JCQuintas
Copy link
Owner

JCQuintas commented Mar 14, 2022

Hi @zaniluca, the main issue is on how the nft package decides which file to bundle or not. A discussion regarding that can be found here: vercel/nft#77

I haven't had the time to look at that more in depth and propose a solution, but in the meantime, the solution provided by @RodriguesCosta should work.

@DerekWolfie
Copy link

Any solution on that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

5 participants