Problems with Now 2 migration - javascript

As stated here on Spectrum, I'm having troubles in migrating my Next website from an Express custom server to Now. My problem is that I'm unable to get the home page, because I'm trying to send URL params, with no success. I need to pass a lang parameter, as follows:
localhost:3000/en
Then, I would have to get the Home as expected. But I'm receiving this exception:
TypeError: Cannot read property 'lang' of undefined at Function.getInitialProps (/Users/lucacattide/Vagrant/debian/public/LC/front-end/.next/server/static/development/pages/_document.js:1111:32)
That's because I was previously reading the ctx.req.params.lang parameter from _document.js getInitialProps for various reasons. Even by replacing it with ctx.req.query.lang I'm still getting it.
I'm currently copying two examples both by Zeit migration guide and article. As both suggest, I'm trying the API approach (https://zeit.co/guides/migrate-to-zeit-now/) and the pages one too (https://zeit.co/guides/custom-next-js-server-to-routes/).
In the API one, I've implemented inside /api path, the [lang].js segment, with the following content:
module.exports = (req, res) => {
res.send(req.query.lang);
}
Then with the /pages one, I copied and renamed the index.js to [lang].js inside the same path, and replaced the req.query.lang as mentioned above. Both of these doesn't work. I'm stuck with the same exception, that warns about _document.js. I need that because of different processes inside it, so deleting it isn't an option in my case.
Of course I'm testing on Now environment (running now dev) on my localhost. The app works perfectly on Express, so I hope to solve this issue in order to deploy it correctly on Now.
Anyone experienced this before or could help me with some suggestion?
Thanks in advance for support.
EDIT:
I tried to force paths too by defining routes in now.json but the result is the same. Here my current configuration:
{
"public": false,
"name": "LC",
"version": 2,
"routes": [{
"src": "/(?<lang>[^/]+)",
"dest": "/?lang=$lang"
}]
}
EDIT 2:
I switched all inside pages dir as suggested from 2nd guide, because I wasn't getting nothing from /api. Trying by placing only a [lang].js route and removing routes definitions from now.json.
At this moment, by inspecting the req object I receive an empty one.

If you are using the passing the lang like this localhost:3000/en then use below snippet to access this
req.params.lang
But if you are passing the lang like this localhost:3000?lang=en
Then use this
req.query.lang

Due to Now platform updates - v2 - I noticed that a lot of Next API parts has changed. By revamping my code in order to following the new approaches, I'm able to get the previously missing parameter.
In details, I followed the API routes tips on the latest official documentation
Thanks everyone for the help.

Related

Getting "URL is malformed "". Please use only absolute URLs" error in Next JS app when attempting to use Airtable JS library in Page

I have a Next JS app with a Page somePage.js. I would like to make an XHR request to the Airtable API from within getServerSideProps. The truncated component is as follows:
pages/somePage.js
import { Component } from 'react';
import Airtable from 'airtable';
export const config = {
runtime: 'experimental-edge',
};
export async function getServerSideProps({ query }) {
Airtable.configure({
endpointUrl: 'https://api.airtable.com',
apiKey: process.env.AIRTABLE_API_KEY,
})
const base = Airtable.base(process.env.AIRTABLE_BASE);
base('someTable').select({...});
return { props: { items: [] } };
}
class SomePage extends Component {
constructor(props) {
super(props);
}
render() {
return (<>...</>);
}
}
export default SomePage;
I get the following error when I do yarn run next dev:
Error: URL is malformed "". Please use only absolute URLs - https://nextjs.org/docs/messages/middleware-relative-urls
This error happened while generating the page. Any console logs will be displayed in the terminal window.
With a stack trace starting in node_modules/next and ending in node_modules/airtable.
The error goes away if I remove airtable related code.
The website linked in the error indicates that URLs must be absolute when used in specific functions (none of which are used in my app in my code, I checked), specifically, in middleware, as in the Next.js middleware paradigm (within a middleware directory, which I also don't have). I assumed the airtable.js library was trying to do some relative query, which I tried to resolve by setting the endpointUrl explicitly, but that didn't solve the issue.
I also tried doing Airtable.configure outside of getServerSideProps, but that didn't change the error.
I checked various other answers on stackoverflow, but their issues all resolved around using middleware, which I don't do, and anyway, their answers didn't seem to be relevant to my issue:
Next JS - Middlewares - Error: URLs is malformed. Please use only absolute URLs : to my knowledge, I'm not making relative URL request
Next JS Middlewares - URLs is malformed. Please use only absolute URLs : same as above
I checked the Airtable API docs, as well as the airtable.js library, but didn't find anything about ensuring all URLs are absolute, nor any helpful tutorials about using next.js with airtable. The tutorials I did find didn't seem to be using airtable in any significantly different way than me.
According to my understanding of the getServerSideProps paradigm of next.js, I should be able to make cross-origin API calls within this function, so I don't see why it would be specifically disallowed.
How can I make API calls to Airtable from within Next JS getServerSideProps?
My versions are as follows:
"airtable": "^0.11.6",
"next": "^13.1.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"webpack": "^4.29.6"
Edit: I have confirmed that literally just importing airtable, or requiring it, causes the error. No need to invoke it.
Edit: This seems to be related to the experimental edge runtime.
This is because the experimental edge runtime is incompatible with the airtable.js library, for various reasons. I don't know the exact cause of the mentioned bug, but basically the experimental edge runtime isn't node, and therefore the airtable library is using incompatible APIs.
See: https://github.com/vercel/next.js/discussions/44843
https://community.cloudflare.com/t/is-the-airtable-js-library-compatible-with-cloudflare-pages/452308/2
Airtable js can be used with nextjs, just not on cloudflare, because cloudflare requires experimental edge runtime for serverside rendered next.js. The deployment solution will have to be able to run the next.js node server if you want to use airtablejs for a serverside rendered app.

Nextjs routing issue: superior param is weird

I have a project using nextjs v12
I have 2 routes that are overlapping in a weird way.
/:academy/:course
/questions/:id
when I load /questions/1 it works as expected
when I load /mit/math it works as expected
The issue:
when I redirect from /questions/1 to /questions/2,
it loads, you guessed it, the other route! (/:academy/:course)
and more, when I refresh the page (after the redirect) it will load the /questions/:id!!!
I tried
check for miss spelling
make /questions/:id -> /aquestions/:id
so, do you know a way to solve this issue?
thanks.
Solved
it was /q/:id and I renamed it to /q/:id.
and because it's with ssr (I think), I had to clear the cache and restart the project.
This should not happen, because according to official nextJS docs,
Predefined routes take precedence over dynamic routes and dynamic
routes over catch-all routes.
https://nextjs.org/docs/routing/dynamic-routes
In this case, it looks like we are trying to use 2 partial dynamic path, that is why nextJS is not able to figure out the correct path, you can add rewrite rule to always send /questions/* paths to /questions/:id
https://nextjs.org/docs/api-reference/next.config.js/rewrites
Can you please share the code how you are redirecting, to help you better?

Rederict path, specified in 'next.config.js' file for one project, has been implemented for all projects

A bit of an odd one...
I've specified a redirect path for the root index page for one of my projects. It worked no problem and redirected me to the correct path, but now it redirects me to that same path for the root index page for all of my other projects. (trying to visit localhost:3000 now redirects me to localhost:3000/ggp for all of my projects)
I've tried restarting servers, deleting the next.config.js file in the original project, commenting out the redirect key, overriding it with a different path in both the original project and in the other project but all to no avail.
This is the first time I've created a next.config.js file and obviously the first time using the redirect key. I was following the guidance in the docs (https://nextjs.org/docs/api-reference/next.config.js/redirects).
At first I thought it might be because I set permanent to true, but that would seem like a bit of a weird feature to make it global and when I run a different project in dev mode (next dev) and debug, everything works normally as it should. So I'm not sure if the value just got cached on first use or something.
Has anybody encountered this before / know a way of fixing it? I'd appreciate your help!
The original next.js.
module.exports = {
async redirects() {
return [
{
source: '/',
destination: '/ggp',
permanent: true,
},
]
},
}
Turns out the problem was that when you set the permanent key to true, it caches the redirect route in the browser (at least it does in Google Chrome), so that redirect route is used for all requests to that path, regardless of which project is active.
Clearing the browser cache and switching the permanent key to false, solves the issue for me (I just opened up the inspector, went to the network tab, right clicked in the network request table and selected "clear browser cache").
It seems like a weird feature to me, especially since it's use seems pretty ambiguous in the docs (although it may be mentioned somewhere that I haven't looked).
Anyway, lesson learned: Test the issue in another browser before tearing your hair out :')

Parse request.object.get("KEY") always returns undefined

I have a strange problem over here. I have a project built with Parse.com as a backend (using cloudcode to verify some things when a connection to the database is made). Everything works just as it should do.
But here comes the problem. Another developer reported to me that there is something wrong because he is getting 'undefined' every time he tries to call request.object.get('KEY')in CloudCode. This developer uses the exact same codebase as I do.
So I decided to have a look at it. While with my Parse account, every application works fine (even newly created ones), with the Parse account of the other developer, not a single new application we created seems to work with the exact same code. And it is getting even stranger - creating a completely new Parse account and a new application produces the same errors while my personal account and applications continue to work fine.
So what is the problem? We are using CloudCode, and here is sample code (in javascript) of a beforeSave method:
Parse.Cloud.beforeSave('Activity', function(request, response) {
var currentUser = request.user;
var objectUser = request.object.get('fromUser');
if(!currentUser || !objectUser) {
response.error('An Activity should have a valid fromUser.');
} else {
response.success();
}
});
And every time request.object.get('KEY') returns undefined, for every key I previously defined in the iOS code before uploading the PFObject.
Note that with my personal account everything is fine...
I have already seen this thread, however deleting ACL's didn't do the trick. request.object.get() stays undefined while request.useris defined for every tested Parse account except mine.
EDIT 1
I also had a look at the activity object just before it is uploaded, and there all the fields are properly set.
EDIT 2
After removing the cloud code completely, the objects are correctly being uploaded to Parse, with all the fields being the way they were set via the iOS client. So it seems that something is wrong with Parse's cloud code, but as soon as an object passes through cloud code, it looses all its fields.
Finally I was able to solve this. This is definitely a bug in Parse's Javascript SDK. I changed the Javascript SDK version in the global.json back to version "1.4.2" instead of "latest", uploaded this to the cloudcode folder and everything went back to normal.
You can also test other versions, maybe v1.5.0 is working too, but as soon as I found out v1.4.2 worked fine, I didn't try out more recent versions.
EDIT
So, I discovered, that Parse must have changed something in their command line tool. It seems that the global.json file isn't there anymore if you create your CloudCode folder with the most recent version of their command line tool. However, you can manually create it and upload the complete folder to your Parse app.
This is how my CloudCode folder looks like, just for example:
CloudCode folder contains three subfolders
• cloud - containing cloud code files
• config - containing the global.json file
• public - containing the index.html file
The global.json file contains these lines of code:
{
"global": {
"parseVersion": "1.4.2"
},
"applications": {
"YOUR_PARSE_APPS_NAME": {
"applicationId": "YOUR_APP_ID",
"masterKey": "YOUR_APP_MASTER_KEY"
},
"_default": {
"link": "YOUR_PARSE_APPS_NAME"
}
}
}

How to get my 404 page to show after upgrade of Sails.js to 0.10.x?

I've upgraded my Sails.js app to 0.10.x and now when I point my browser at a non-existent route such as http://localhost:1337/notfound instead of my views/404.jade being served up I just get a bit of JSON
{
"status": 404
}
I built a default new sails app sails new dummy --template=jade just to compare and contrast with what I have in my existing app, and the only obvious difference I see is that in dummy/config/ there is a file called http.js
I've copied that file over to my app but it's made no difference.
I've also ensured that the tasks in dummy/tasks are identical to my own app's tasks.
In dummy/config/routes.js it says
Finally, if those don't match either, the default 404 handler is triggered.
See config/404.js to adjust your app's 404 logic.
Which is obviously out of date as 0.10.x apps use the api/responses mechanisms.
So I am at rather a loss as to how to get this to work.
I am using 0.10.0-rc8 (and I have confirmed that this is the same in my dummy app as well as my actual app)
Well I've fixed this but I have no idea why it was happening.
To fix it I created a new project as per the method described in my question, but with the same name as my existing project, then, file-by-file, I painstakingly moved across everything specific to my app, taking care to leave in place anything new generated by sails.
Once I'd done that I ran my tests - all passed - and then sails lift and tried it, and yay, everything worked and I got my 404 error page back.
I committed my changes and then carefully picked through a comparison of what had changed.
Alas nothing at all stands out, so, while I have solved my problem, I have no idea what the original cause was.
From the section in the migration guide on "Custom Responses":
In v0.10, you can now generate your own custom server responses. See
here to learn how. Like before, there are a few that we automatically
create for you. Instead of generating myApp/config/500.js and other
.js responses in the config directory, they are now generated in
myApp/api/responses/. To migrate, you will need to create a new v0.10
project and copy the myApp/api/responses directory into your existing
app. You will then modify the appropriate .js file to reflect any
customization you made in your response logic files (500.js,etc).
Basically, v0.10.x gives you more freedom in how things like res.notFound, res.serverError and even res.ok() (success response) work, but you need to copy over the new api/responses folder to migrate.
I had the same issue but was using 0.9.x. Probably a better solution but I outputted a view instead of JSON in all cases.
Update config/404.js to replace res.json() with res.view():
if (err) {
//return res.json(result, result.status); }
return res.view('404') // <-- output the 404 view instead
}
Then, just make sure in your routes.js file it will redirect the /404. Place the following at the bottom of your routes.js file:
'/*': {
view: '*'
},

Categories

Resources