I got a simple Next app where I'm making an external API call to fetch some data. This worked perfectly fine until a couple days ago - when the app is making an API request, I can see in the network tab that the URL that it's trying to call, got Next app's address (localhost:3000) prepended in front of the actual URL that needs to be called e.g.: instead of http://{serverAddress}/api/articles it is calling http://localhost:3000/{serverAddress}/api/articles and this request resolves into 404 Not Found.
To make the API call, I'm using fetch. Before making the request, I've logged the URL that was passed into fetch and it was correct URL that I need. I also confirmed my API is working as expected by making the request to the expected URL using Postman.
I haven't tried using other library like axios to make this request because simply it doesn't make sense considering my app was working perfectly fine only using fetch so I want to understand why is this happening for my future experience.
I haven't made any code changes since my app was working, however, I was Dockerizing my services so I installed Docker and WSL2 with Ubuntu. I was deploying those containers on another machine, now both, the API I'm calling and Next app are running on my development machine directly when this issue is happening.
I saw this post, I confirmed I don't have any whitespaces in the URL, however, as one comment mentions, I installed WSL2, however, I am not running the app via WSL terminal. Also, I've tried executing wsl --shutdown to see if that helps, unfortunately the issue still persists. If this is the cause of the issue, how can I fix it? Uninstall WSL2? If not, what might be another possible cause for the issue?
Thanks in advance.
EDIT:
The code I'm using to call fetch:
fetcher.js
export const fetcher = (path, options) =>
fetch(`${process.env.NEXT_PUBLIC_API_URL}${path}`, options)
.then(res => res.json());
useArticles.js
import { useSWRInfinite } from 'swr';
import { fetcher } from '../../utils/fetcher';
const getKey = (pageIndex, previousPageData, pageSize) => {
if (previousPageData && !previousPageData.length) return null;
return `/api/articles?page=${pageIndex}&limit=${pageSize}`;
};
export default function useArticles(pageSize) {
const { data, error, isValidating, size, setSize } = useSWRInfinite(
(pageIndex, previousPageData) =>
getKey(pageIndex, previousPageData, pageSize),
fetcher
);
return {
data,
error,
isValidating,
size,
setSize
};
}
You might be missing protocol (http/https) in your API call. Fetch by default calls the host server URL unless you provide the protocol name.
Either put it into env variable:
NEXT_PUBLIC_API_URL=http://server_address
Or prefix your fetch call with the protocol name:
fetch(`http://${process.env.NEXT_PUBLIC_API_URL}${path}`, options)
Related
I'm using Next.js with Storyblok and recently made use of the react-next-boilerplate.
I noticed that they put the preview token in the _app.js, so essentially publish it:
storyblokInit({
accessToken: "your-preview-token",
use: [apiPlugin],
components,
});
If I use an environment variable instead, which isn't available on the client, I get the error
You need to provide an access token to interact with Storyblok API
in the client. That's because (I think) my components use StoryblokComponent, which makes use of the global Storyblok state. So I wonder:
Should I ignore this error, as I don't plan to interact with the Storyblok API other than using it for component rendering (all the data comes from the server, as far as I understand the concept of static site generation), and component rendering seems to be still working?
Should I just publish the preview token?
Should I create two tokens, one for the server and one for the client?
Setting the token to process.env.STORYBLOK_API_KEY || "NULL" (where "NULL" can be anything except the empty string) also works (no more errors) but seems like a weird solution.
I don't really understand why they combine these two things, component rendering and data fetching, in the same function.
I would use a .env.local file and populate it with:
STORYBLOK_API_KEY=your-preview-token
To use the environment variable inside _app.js you have to pass it to next.config.js like this:
module.exports = {
env: {
STORYBLOK_API_KEY: process.env.STORYBLOK_API_KEY,
}
}
Source: https://nextjs.org/docs/basic-features/environment-variables
I'm using Meteor v1.9 Webapp API to have my app listen to HTTP requests, specifically from a link to the app itself from a website, let's say example.org.
The documentation says to use
WebApp.connectHandlers.use([path], handler)
Where the [path] is defined as such:
path - an optional path field. This handler will only be called on
paths that match this string. The match has to border on a / or a ..
For example, /hello will match /hello/world and /hello.world, but not
/hello_world.
My question:
Let's say my meteor application is hosted on abc.com and the POST data being sent over to it is from example.org (where the link to abc.com is as well).
For the [path] argument mentioned above, in this case, should I have it as "/example" since example.org is where my app is listening to requests from (getting the POST data)? Or does it have to be a different format? I tried the former, but it doesn't seem to be working for it, so I'm trying to find the root of the issue.
Additional information that might be useful: I know it says 'optional' so I tried omitting it, but when I tested it out via 'meteor run' where it runs off of localhost:3000, it just yielded a blank page, with no errors and a success sent back, probably because it uses a GET request instead of POST.
My code for the webapp in my meteor application is as follows:
WebApp.connectHandlers.use("/[example]", async (req, res, next) => {
userName = req.body;
res.writeHead(200);
res.end();
});
Also technically my meteor application is built/bundled and deployed as a Node.js application on the website, but that shouldn't affect anything regarding this as far as I could tell.
That path is the path (part of the URL) on your meteor server. So in your example, for instance,
WebApp.connectHandlers.use("/example", async (req, res, next) => {
userName = req.body;
res.writeHead(200);
res.end();
});
means that you will need to send your POST requests to abc.com/example.
I have site that deployed on firebase hosting site
on the site I wrote Version 3 but instead of that I want to show the deployment / release version like e925c5 that writen on the history version.
can I get history version with Rest API.? or can I define it before deployed.?
thank you
Update
I try with reading documentation and working with it, but still stuck with the authentication method,
Simple function is this, but always returned 403 response, already try with getGlobalDefaultAccount.login() and getGlobalDefaultAccount.getAccessToken() and getGlobalDefaultAccount() still not working,
const requireAuth = require('firebase-tools/lib/requireAuth')
const getGlobalDefaultAccount = require('firebase-tools/lib/auth')
const api = require('firebase-tools/lib/api')
const site = 'sarafe-testing'
requireAuth(getGlobalDefaultAccount.getAccessToken(), ['https://www.googleapis.com/auth/cloud-platform']).then(async () => {
try {
const response = await api.request('GET', `/v1beta1/sites/${site}/releases`, { auth: true, origin: api.hostingApiOrigin })
console.log(response)
} catch(e) {
console.log(e.message)
}
})
Full version
For now I just created table that hold version code (manuali update from firebase page) and make API to get the version, but this not a valid solution because is only show the latest version, some other people just open the webpage without refresh / clear cache so that one is still using the old version of webpage with latest version written,
Yes, there is a REST API that allows you to manage versions and releases for Firebase Hosting, and it has a method to get a list of versions for the site. I recommend checking out its documentation and reporting back if you get stuck while implementing the code.
been playing around with a simple blog built with JSONPlaceholder and Nuxt.js
Everything seems fine, I've got an archive and single blog posts working fine but when deployed on Netlify I can see that the browser is still doing API calls to JSONPlaceholder even though all the pages are built static and I can see they already have the content within the HTML.
I used the routes method within generate in the nuxt config to create the 100 html files based upon the JSONPlaceholder /posts results.
Here's the Netlify link: REMOVED.
And a public repo: https://bitbucket.org/oneupstudio/api-test/src/master/
Anything I've missed?
Nuxt.js doesn't support 'full static generation' yet, check this RFC.
For now, you can use this module in order to make your JSON requests static.
Nuxt currenty supports proper static generation of websites. Although one has to be aware of payload param in asyncData. So if payload is present that indicates that static generator is at work and no api calls should be made in this case:
async asyncData ({ params, error, payload }) {
if (payload) return { user: payload }
else return { user: await backend.fetchUser(params.id) }
}
Read more on this here.
RFC mentioned by #DreadMinder will further improve on this, but you can already do full static websites with Nuxt.
I can successfully send a web hook from Stripe to my Meteor app in development using ngrok. For example, my test endpoint on the Stripe dashboard would be sent to something like https://f5f62fdf.ngrok.io. It responds with a successful notice. The ngrok inspector shows the stripe test object received. But in Meteor I'm a little unsure how the router should look with ngrok. On the server, my route would be something like:
Router.route( "<unsure what path to put here>", function() {
console.log('hello');
}, { where: "server" });
In my testing environment using ngrok, what would the path be?
Just trying to get the function to console.log() my 'hello' so I know it's working.
OK, I'm an idiot. It console.logs to the terminal, not the browser. Ouch. Given I'm working with Node, it makes sense. Just for posterity, the Stripe endpoint would be something like https://g4r62fdf.ngrok.io/stripe/webhook.
Make sure you're returning a response inside the function so the web hook won't timeout.
this.response.statusCode = 200;
this.response.end('10-4, good buddy');