Closed katspaugh closed 3 years ago
Yeah, Next.js 10 just came out two days ago, so it'll take some time to add those new features, since we have custom routing/rendering logic optimized for Lambda@Edge. I've tagged this with enhancement.
But I've tested the existing end-to-end tests with Next.js 10 and nothing broke, so looks like all the existing features work as expected.
I am also have the same issue 404
on not root pages.
/en
for example) though, there is a strange behaviour when refreshing page that has locale subpath:
Hi! I was wondering if there are any updates on this?
Yes, I have not had a chance to look at it yet, been mostly on vacation mode the past few weeks so haven't worked on the code recently. Hoping to get to it once I'm back next week :)
Thanks for the update! :) If it helps, when I tried deploying my site with the i18n solution it worked well on all locales, except for the default one, which returned 404 for all routes unless I manually added the locale prefix to the URL path.
Hope you enjoy the rest of your holiday! :)
Hi, I was wondering if there was any updates on this issue?
I am planning to continue on this during this week. Apologies since lately I was the only contributor for this, so haven't had enough time to both triage issues and work on the codebase..
From initial looks, Next.js will generate new pages for each locale specified (for SSG). So then we would need to just create new routes in our manifests to direct the locale-prefixed paths to the right SSG pages. And without a local-prefix, it should use specified defaultLocale
instead. For SSR pages, there is only a single JS file.
Have published @sls-next/serverless-component@1.19.0-alpha.29
which should have locale subpath routing working. Note that you do need to add Accept-Language
header for the root-level locale redirect (it's added by default in default behavior, but if you override it, you will have to add it yourself).
I haven't extensively tested it nor added complete tests for it yet, so please treat it as a preview for now and report any issues by opening a bug report. Thanks!
Note: domain-based routing will be a separate issue
Thanks for the update, everything is working as expected for us, except for the index.js page when using getStaticProps.
For all locales, the base path returns an AccessDenied error due to index.html not being exported properly to the static-pages folder in S3. All other static routes are being exported properly. Using the trailingSlash config does not solve this issue, and changing getStaticProps to getServerSideProps renders the index path as expected. Let me know if you need more information!
@testreen thanks! Let me take a look and fix that today. I might have missed testing getStaticProps
on index page (only with getServerSideProps
.
Hey, many thanks for your update!
I've bumped my app to the latest serverless version, and I seem to experience these issues:
accept-lang
header via my browser./es
returns an s3 error (I wasn't experiencing in the previous version of the serverless alpha release) Any ideas what could be causing this?
How to possibly reproduce this: my current next.config.js
module.exports = {
i18n: {
locales: ['en', 'es'],
defaultLocale: 'en',
},
}
this is my serverless config:
allthemeasurements:
component: "@sls-next/serverless-component@1.19.0-alpha.29"
inputs:
bucketName: xxx
domain: "xxx.xxx" # sub-domain defaults to www
roleArn: arn:aws:iam::xxxx
name:
defaultLambda: UI
cloudfront:
distributionId: xxxx
defaults:
forward:
cookies: "none"
Yea, I will rework some of the changes today. Basically with locales then data files and pages would be put into locale-prefixed paths e.g /en/
, however for locale index pages it is stored in root as en.html
or en.json
if you have made it statically generated, instead of index.json
or index.html
as expected. So it is why there is a 403 access denied.
As fix we need to copy en.html
en.json
files correctly and reference those instead. Probably easier to rewrite /
-> /en
internally so that is can reference the en.html
page.
Also if using locales, we can just have locale directories e.g /en
, /nl
and then just rewrite all non-locale-prefixed URLs to add the default locale prefix. E.g /
-> /en
, /another
-> /en/another
, so we don't have to maintain default locale pages at the root level too. And also makes fallback page generation easier, since Next.js requests data file using locale path, e.g _next/data/build-id/en/not-yet-generated.json
and we just need to generate a page /en/not-yet-generate.html
.
@dphang all's good for me in production , but i have the same issue mentioned here https://github.com/serverless-nextjs/serverless-next.js/issues/646 all SSG routes with getStaticPaths` fail with 503
all i18n sub routes with SSG are not uploaded to S3 with local path like /_next/data/buildID/fr/auth/signin.json
probably a problem with dataRoutes
and 'dataRoutes` in routes-manifest
Thanks @benjipott for reporting, for that issue #646 I didn't have luck making progress on it. But will look at the other issue.
@dphang with my latest pr approved and merged, i test only the upload to s3 but i think an other method filter this file because /fr/path/file.json is correctly present in next folder ... no idea why. I can check it in your related issue, thks @dphang
@johnaxe not sure, I did not change anything client-side, so perhaps it might be Next.js converting the link component to wrong href? Is that the same behavior on the local dev server?
I have noticed one use case that SSG with nextjs i18n only working from the root page (index.jsx). I put the same code on all pages for testing.
/ => working
/en => working
/ssg-home. => not working
/en/ssg-home => not working
Here is my serverless.yml
configuration
pocOptim:
component: '@sls-next/serverless-component@1.19.0-alpha.31'
inputs:
memory: 512
useServerlessTraceTarget: true
This is my i18n
config for next.config.js
i18n: {
localeDetection: false,
locales: ['en', 'de'],
defaultLocale: 'en'
},
@krish-dev thanks, I will take a look, not sure if it's due to serverless trace target (I have only tested without it)
You are correct @dphang, I did some testing without useServerlessTraceTarget: true
then it works, but with useServerlessTraceTarget
the behavior is the same as I described. However, useServerlessTraceTarget: true
is very crucial for the application which has a very long list of SSR pages.
I have noticed one use case that SSG with nextjs i18n only working from the root page (index.jsx). I put the same code on all pages for testing.
/ => working /en => working /ssg-home. => not working /en/ssg-home => not working
@dphang any luck for useServerlessTraceTarget: true
issue?
Haven't finished looking at it yet, I was fixing some other locale bugs and e2e tests. I need to check the .next output structure for serverless-trace target and see if files are being copied correctly. Planning to wrap up this feature this week.
Hi, @dphang ! What is the status for this fix?
I noted that I have issue related to localization stuff. It is an error new Error('next-i18next was unable to find a user config')
thrown from default-lambda/pages/index.js
, function serverSideTranslations
. It looks like I have no defined userConfig
or something? I tried to fix it by manual copying next-i18next.config.js
to default-lambda main folder, but after that I reached only another one error:
ERROR Unhandled Promise Rejection { "errorType": "Runtime.UnhandledPromiseRejection", "errorMessage": "Error: Cannot find module '/var/task/next-i18next.config.js'", "reason": { "errorType": "Error", "errorMessage": "Cannot find module '/var/task/next-i18next.config.js'", "code": "MODULE_NOT_FOUND", "stack": [ "Error: Cannot find module '/var/task/next-i18next.config.js'", " at webpackEmptyContext (/var/task/pages/index.js:91038:10)", " at /var/task/pages/index.js:1552:90" ] }, "promise": {}, "stack": [ "Runtime.UnhandledPromiseRejection: Error: Cannot find module '/var/task/next-i18next.config.js'", " at process.<anonymous> (/var/runtime/index.js:35:15)", " at process.emit (events.js:314:20)", " at processPromiseRejections (internal/process/promises.js:209:33)", " at processTicksAndRejections (internal/process/task_queues.js:98:32)" ] }
I am having the same issues as @peniakoff . The problem is that the next-i18next.config.js
file does not get bundled. You can pass the configuration directly to the method but then it complains that the locales files are missing. Any way to get them bundled ?
@poppein @peniakoff Sorry, I am not too sure how it works as I don't use next-i18next yet. You may need to use postBuildCommands
to run a script to manually copy any needed files into the Lambda folder before the upload. As this component does not know about those additional plugins. Feel free to share the script and/or integrate the copying for next-18next.
@krish-dev sorry for delay, been busy last couple of weeks with moving. I did test the e2e locales test app (next-app-with-locales
) in different ways but still could not reproduce any issue that you saw. SSG assets are copied correctly and am able to view ssg page under /fr/ssg-page
and also /en
, /fr
etc. For example: https://d1f9sulga5gpon.cloudfront.net/fr/ssg-page.
Here is how assets looks like, all data files and pages are copied correctly:
In default lambda pages are also copied correctly (actually no difference from non-locale app since these are only the SSR pages), they are liightweight pages + node_modules
folder:
If possible could you please try to modify the e2e-tests/next-app-with-locales
app to reproduce the issue. Maybe there is some other config that is different?
Getting the following deployment error now, which did not exist in previous versions:
error:
RequestEntityTooLargeException: Request must be smaller than 69905067 bytes for the UpdateFunctionCode operation
at Object.extractError (/Users/rammarketinginternational/.serverless/components/registry/npm/@sls-next/serverless-component@1.19.0-alpha.41/node_modules/aws-sdk/lib/protocol/json.js:52:27)
at Request.extractError (/Users/rammarketinginternational/.serverless/components/registry/npm/@sls-next/serverless-component@1.19.0-alpha.41/node_modules/aws-sdk/lib/protocol/rest_json.js:55:8)
at Request.callListeners (/Users/rammarketinginternational/.serverless/components/registry/npm/@sls-next/serverless-component@1.19.0-alpha.41/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/Users/rammarketinginternational/.serverless/components/registry/npm/@sls-next/serverless-component@1.19.0-alpha.41/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/Users/rammarketinginternational/.serverless/components/registry/npm/@sls-next/serverless-component@1.19.0-alpha.41/node_modules/aws-sdk/lib/request.js:688:14)
at Request.transition (/Users/rammarketinginternational/.serverless/components/registry/npm/@sls-next/serverless-component@1.19.0-alpha.41/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/Users/rammarketinginternational/.serverless/components/registry/npm/@sls-next/serverless-component@1.19.0-alpha.41/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /Users/rammarketinginternational/.serverless/components/registry/npm/@sls-next/serverless-component@1.19.0-alpha.41/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.
@rmulder I believe your issue is this: https://github.com/serverless-nextjs/serverless-next.js/issues/979 please follow or reply to that issue instead of here, since it should not be related to Next.js 10 localization
@dphang - You are absolutely correct. I re-ran the deploy with alpha.42 version (which is now out) - and that problem has been resolved. My code deploys, and thus far the i18n issues I had been experiencing have been resolved. Thanks!
@poppein @dphang I'm currently experiencing the next-i18next.config.js
non-bundling error as well.
Error: Cannot find module '/builds/<project>/next-i18next.config.js' at webpackEmptyContext (/builds/<project>/.next/serverless/pages/index.js:45452:10) at /builds/<project>/.next/serverless/pages/index.js:803:90
Can either of you share a solution which might help address this? I tried adding a postBuildScipts
which looks like this
fs.copySync('./next-i18next.config.js', '/builds/<project>/next-i18next.config.js', { recursive: true });
but no dice.
Any suggestions?
@rhoiyds I unfortunately revert back to using plain react i18next and not next-18next as i couldn't get it to bundle properly
@poppein Thank you for letting me know - however that is sad to hear. I'm afraid I might have to do the same, unless @dphang has found a solution.
@rhoiyds I ve managed to make it work by copying my next-i18next.config.js
in both the root of my project (alongside next-config) and in my /src
folder. I hope it will work for you.
Great to hear that @gouroujo! Did you manually copied this or do you have some task that you could share?
@gouroujo Thanks for sharing your solution! I had really high hopes for it, however, unfortunately still no dice. The same error as always. If there's anything else you can share that might help, it would be greatly appreciated.
Hi all, after days of headaches I've managed to find a workaround which seems to work for me. Here's some notable configs that managed to work for me, no guarantees for anyone else I suppose.
Removed target: 'serverless'
from next.config.js
. Also added i18n configs manually.
module.exports = {
i18n: {
defaultLocale: 'ja',
locales: ['en', 'ja']
}
};
Changed the next-i18next.config file from a .js to a .ts
Updated the contents of the next-i18next.config.ts
file to a duplication of what is defined in the next.config.js
i18n field.
export const i18n = {
defaultLocale: 'ja',
locales: ['en', 'ja']
}
In tsconfig.json (root of the project) I included the newly created next-i18next.config.ts
file.
{
"compilerOptions": {
"rootDirs": ["src/", "types/", "pages/", "lib/", "components/"],
"target": "esnext",
"module": "esnext",
"jsx": "preserve",
"lib": ["dom", "es2017"],
"moduleResolution": "node",
"allowJs": true,
"noEmit": true,
"strict": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"removeComments": false,
"preserveConstEnums": true,
"sourceMap": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"isolatedModules": true
},
"exclude": ["node_modules"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "next-i18next.config.ts"]
}
In _app.tsx
, when wrapping the application with the appWithTranslation
function, I imported the variable from previously made next-i18next.config.ts
config, and passed it as a second parameter to the appWithTranslation function call.
import React, {FC} from 'react';
import {AppProps} from 'next/app';
import { appWithTranslation } from 'next-i18next'
import i18n from '../next-i18next.config'
const WrappedApp: FC<AppProps> = ({ Component, pageProps }) => {
return (
<Component {...pageProps} />
)
}
export default appWithTranslation(WrappedApp, {i18n})
And did so similarly with any page that needs getStaticProps
, example page below:
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
import { useTranslation } from 'next-i18next'
import i18n from '../next-i18next.config'
const TestPage = ({}: Props) => {
const { t } = useTranslation('common')
return (
<>
{t('test')}
</>
)
}
export const getStaticProps = async ({ locale } : any) => ({
props: {
...await serverSideTranslations(locale, ['common'], {i18n}),
}
})
export default TestPage
What an absolute pain that was. I hope this helps anyone out there with the same issue. Also hope this gets resolved and that serverless next.js can properly locate the module without needing to duplicate the configs.
Just some musings: It seems when you run serverless
it duplicates the next-i18next.config.js
file and creates another file like next-i18next.config.original<hash>.js
not sure if that's the issue or not...
Can provide more details of my projects configs if necessary. Good luck all.
Thanks all for the help, let me look into it next. Unfortunately I am not using next-i18next myself yet and don't have enough time to look at various integrations (being the primary contributor to this) so I will take a look and try to repro & fix for the next minor version
@rhoiyds' approach worked. You can see the same conclusion here: https://github.com/isaachinman/next-i18next/issues/990#issuecomment-795398532
Guys, is the automatic locale selection working for you guys in AWS/LambdaEdge? I can access the routes by directly pointing to them but the locale selection/redirection is not working (i.e. it just stays in english, the default).
Guys, is the automatic locale selection working for you guys in AWS/LambdaEdge?
I can access the routes by directly pointing to them but the locale selection/redirection is not working (i.e. it just stays in english, the default).
Are you forwarding the Accept-Language header in CloudFront configuration? This is needed to detect the user's locale
Yes, that seems to be the problem, I'm checking how to change the Cloudfront behavior (I thought it was done :) )
Guys, is the automatic locale selection working for you guys in AWS/LambdaEdge? I can access the routes by directly pointing to them but the locale selection/redirection is not working (i.e. it just stays in english, the default).
Are you forwarding the Accept-Language header in CloudFront configuration? This is needed to detect the user's locale
So I tried this, and things sadly didn't work as expected.
I added Accept-Language to the nextjs serverless configuration.
When my Language is 'es' and I land on mywebsite.com/
I get redirected to mywebsite.com/es
and then I notice an infinite 307 redirects to /es
after this
After I removed the Accept-Language Header in the serverless configuration, I still see it in Cloudfront (see screenshot) for the Path Pattern Default (*)
. (Not sure what I need to add in the serverless config so I stop seeing it appear in Cloudfront😞 )
Update: I ended up putting headers: "none" for the time being.
On my case it is working as expected, weird.
Leaving the CDK code just in case it is useful for someone:
const cachePolicy = new CachePolicy(this, `DefaultCachePolicy${capitalize(env)}`, {
cachePolicyName: `DefaultCachePolicy${capitalize(env)}`,
comment: 'The default policy to be used in the cache',
cookieBehavior: CacheCookieBehavior.all(),
headerBehavior: CacheHeaderBehavior.allowList('Accept-Language'),
queryStringBehavior: CacheQueryStringBehavior.all(),
enableAcceptEncodingGzip: true,
enableAcceptEncodingBrotli: true, // spellchecker: disable-line
});
const nextLambdaEdge = new NextJSLambdaEdge(this, `Cloudfront${capitalize(env)}`, {
...
defaultBehavior: {
cachePolicy
}
});
Guys, is the automatic locale selection working for you guys in AWS/LambdaEdge? I can access the routes by directly pointing to them but the locale selection/redirection is not working (i.e. it just stays in english, the default).
Are you forwarding the Accept-Language header in CloudFront configuration? This is needed to detect the user's locale
So I tried this, and things sadly didn't work as expected.
I added Accept-Language to the nextjs serverless configuration. When my Language is 'es' and I land on mywebsite.com/ I get redirected to
mywebsite.com/es
and then I notice an infinite 307 redirects to/es
after thisAfter I removed the Accept-Language Header in the serverless configuration, I still see it in Cloudfront (see screenshot) for the Path Pattern
Default (*)
. (Not sure what I need to add in the serverless config so I stop seeing it appear in Cloudfront😞 )Update: I ended up putting headers: "none" for the time being.
It was giving me this error too when using the latest version @sls-next/serverless-component@1.19.1-alpha.7 - but I managed to fix it by downgrading to the latest stable version (@sls-next/serverless-component@1.19.0) and now it works fine.
By the way, somebody found how to fallback to the most approximate locale?
Example:
// next.config.js
module.exports = {
i18n: {
locales: ['en', 'es''],
defaultLocale: 'en',
},
}
When I hit with Accept-Language: 'es-ES'
instead of falling back to 'es' it falls back to 'en' (which is a little bit awkward since locale='es' would be much more appropriate). Does it needs to be custom made?, or is there some trick we can use?
@ignaciolarranaga I'm having the same problem. It works fine locally, but not after deploying to production.
Update: it seems to be an issue with Next.js https://github.com/vercel/next.js/issues/20488
Hey, just migrated to 1.9.0-alpha.4 and keeps in loop when not correctly recognize the locale.
For example, My browser by default sends: accept-language: es-419,es;q=0.9
, this forces the jump to /es
but later keeps looping over that.
I think most of the major issues (locale redirection, precedence etc.) should be fixed now in the latest versions, so I'll close this and please open a new issue so it's easier to track specific issues. Thanks!
Sorry to continue the discussion, but I reverted all of my previously mentioned changes, updated to the latest version of serverless component as well as nexti18next and tested a serverless deployment. It successfully deploys, however all I get is 404's on all of my routes.
Sorry to continue the discussion, but I reverted all of my previously mentioned changes, updated to the latest version of serverless component as well as nexti18next and tested a serverless deployment. It successfully deploys, however all I get is 404's on all of my routes.
Can you post any more details of .serverless_nextjs directory / manifests and also if there is any reproduction you can share. Might be good to open a new issue so it's easier to isolate the problem?
The new built-in localization in Next.js 10 allows to have the locale as a path prefix, e.g.:
All three routes will open
pages/about.tsx
. This works fine when I run it locally. When I deploy it using serverless-next.js, it gives a 404 for/de/about
and/es/about
. Just/about
still works.Is this something that the Serverless Next.js Component doesn't support yet, or am I doing something wrong? Thanks!