Error wooCommerce REST API : woocommerce_rest_cannot_view - reactjs

I have some difficulties accessing my wooCommerce API with react and nextjs.
I always have this message : woocommerce_rest_cannot_view
I tried the response I've seen on other thread on stackoverflow, but nothing worked for me.
Here my server.js
const next = require('next');
const express = require('express');
const wooConfig = require( './wooConfig' );
const WooCommerceAPI = require('woocommerce-api');
// import WooCommerceRestApi from "#woocommerce/woocommerce-rest-api"; // Supports ESM
const WooCommerce = new WooCommerceAPI({
url: wooConfig.siteUrl,
consumerKey: wooConfig.consumerKey,
consumerSecret: wooConfig.consumerSecret,
wpAPI: true,
version: 'wc/v1',
query_string_auth: true
});
const port = 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
app.prepare()
.then(() => {
const server = express();
server.get('/getProducts', (req, response) => {
WooCommerce.get('products', function (err, data, res) {
response.json(JSON.parse(res));
});
})
server.get('*', (req, res) => {
return handle(req, res);
});
server.listen(port, err => {
if (err) {
throw err;
}
console.log(`Ready on port ${port}`)
})
})
.catch(ex => {
console.error(ex.stack);
process.exit(1);
});;

I found the solution :
This is
queryStringAuth: true
instead of
query_string_auth: true

Related

create Websocket with custom NextJS server

I'm runnung NextJS application with a custom server to establish a websocket between the frontend and the custom backend.
Here is the custom server:
const express = require("express");
const next = require("next");
const emitter = require("./lib/eventEmitter");
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== "production";
const app = next({ dev });
const handle = app.getRequestHandler();
const server = express();
const http = require('http')
const socketIo = require("socket.io");
const wbServer = http.createServer(server)
const io = socketIo(wbServer);
io.on("connection", (socket) => {
console.log("client connected: ", socket.id);
});
app.prepare().then(() => {
server.all("*", (req, res) => {
return handle(req, res);
});
server.listen(port, () => {
console.log(`> Ready on http://localhost:${port}`);
});
});
Here is the frontend connection:
useEffect(() => {
(async () => {
let socket = io("http://localhost:3000");
socket.on("connected", () => {
console.log("Connected");
});
})();
});
but it's not connecting React is showing 404 error like this:
XHR GET http://localhost:3000/socket.io?EIO=4&transport=polling&t=ODFLYBM
[HTTP/1.1 404 Not Found 8ms]
The answer is listening to wbServer instead of server like this:
const server = require("http").Server(app);
server.listen(port, () => {
console.log(`> Ready on http://localhost:${port}`);
});

Next js with express dynamic path handling

I am trying to create dynamic route for my web application but the path are not working as it suppose to this is my server.js file
const express = require("express");
const next = require("next");
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== "production";
const app = next({ dev });
const handle = app.getRequestHandler();
const { parse } = require("url");
app.prepare().then(async () => {
const server = express();
server.get("/:id", (req, res) => {
const parsedUrl = parse(req.url, true);
const { pathname, query } = parsedUrl;
app.render(req, res, "/", query);
});
server.get("/home", (req, res) => {
const parsedUrl = parse(req.url, true);
const { pathname, query } = parsedUrl;
app.render(req, res, "/home", query);
});
server.get("/category", (req, res) => {
app.render(req, res, "/category");
});
server.get("*", (req, res) => {
const parsedUrl = parse(req.url, true);
const { pathname, query } = parsedUrl;
return handle(req, res, "/", parsedUrl);
});
server.listen(port, (err) => {
if (err) throw err;
});
});
I need to dynamically get the id from path that will come after url, what is happening is no matter what I write after my local host it always go thrugh server.get(* .. part. please help.

HTTPS on localhost using NextJS + Express

System Information
Express: 4.16.4
NextJS: 8.0.3
React: 16.8.4
ReactDOM: 16.8.4
Goal
Serve the web application using SSL over HTTPS on localhost
What has been done
Created basic NextJS application using Create Next App
Generated a certificate and key using OpenSSL and moved it into the project directory
Added the Express dependency
Configured the app to use express inside server.js
Changed script to use the server.js inside package.json scripts.
server.js
const express = require('express');
const next = require('next');
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
const port = 3000;
const https = require('https');
const fs = require('fs');
const httpsOptions = {
key: fs.readFileSync('./certificates/key.pem'),
cert: fs.readFileSync('./certificates/cert.pem')
};
app
.prepare()
.then(() => {
const server = express();
server.get('*', (req, res) => {
return handle(req, res);
});
server.listen(port, err => {
if (err) throw err;
console.log('> Ready on http://localhost: ' + port);
});
})
.catch(ex => {
console.error(ex.stack);
process.exit(1);
});
Extra Information
The app currently works when initialized using yarn dev. I have tried to serve the app over https using this answer but I was unable to figure out how to apply this to my current setup using NextJS.
I spent a lot of time researching the web how to apply this solution but have not yet found a way on how to make this work.
Any help is greatly appreciated.
You just need to use the createServer method of https module.
const { createServer } = require('https');
const { parse } = require('url');
const { readFileSync } = require('fs');
const next = require('next');
const port = 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
const httpsOptions = {
key: readFileSync('./certificates/key.pem'),
cert: readFileSync('./certificates/cert.pem')
};
app.prepare()
.then(() => {
createServer(httpsOptions, (req, res) => {
const parsedUrl = parse(req.url, true);
handle(req, res, parsedUrl);
}).listen(port, err => {
if (err) throw err;
console.log(`> Ready on https://localhost:${port}`);
})
});
Other answer seemed to just drop express... Found a solution after some difficulty with both server code and certificate so hopefully can save someone else the trouble!
First of all, solid advice for creating localhost certificate here:
https://letsencrypt.org/docs/certificates-for-localhost/
Secondly, simple code that offers HTTP/HTTPS with next js and express:
const next = require('next');
const express = require('express');
const http = require('http');
const https = require('https');
const fs = require('fs');
const ports = {
http: 3080,
https: 3443
}
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
const server = express();
const options = {
key: fs.readFileSync('localhost.key'),
cert: fs.readFileSync('localhost.crt'),
};
app.prepare().then(() => {
server.all('*', (req, res) => {
return handle(req, res)
});
http.createServer(server).listen(ports.http);
https.createServer(options, server).listen(ports.https);
});
It is worth noting that one could omit or redirect either port.
Below work for me very well for next server with https;
Using this official documentation of node js https module Creating HTTPS Server
const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')
const { readFileSync } = require('fs');
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
const httpsOptions = {
pfx: readFileSync('./certificates/AMB.pfx'),
passphrase: 'Testabc$'
};
app.prepare().then(() => {
createServer(httpsOptions, (req, res) => {
const parsedUrl = parse(req.url, true)
const { pathname, query } = parsedUrl
if (pathname === '/login') {
app.render(req, res, '/login', query)
} else {
handle(req, res, parsedUrl)
}
}).listen(port, err => {
if (err) throw err
console.log(`> Ready on https://localhost:${port}`)
})
})
Our straightforward, switchable implementation:
const app = require('express')();
const https = require('https');
const http = require('http');
const next = require('next');
const fs = require('fs');
const path = require('path');
const HTTPS = true;
const server = HTTPS
? https.createServer(
{
key: fs.readFileSync(path.resolve(__dirname, './server.key')),
cert: fs.readFileSync(path.resolve(__dirname, './server.cert')),
},
app
)
: http.createServer({}, app);
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const nextApp = next({ dev });
const nextHandler = nextApp.getRequestHandler();
nextApp.prepare().then(() => {
app.get('/api/something', (req, res) => {
res.json({});
});
// ...
app.get('*', (req, res) => {
return nextHandler(req, res);
});
server.listen(port, (err) => {
if (err) throw err;
console.log(`> Ready on http${HTTPS ? 's' : ''}://localhost:${port}`);
});
});

Endpoint returns 404 when using custom Express server

I have a Next.js app with two pages. My structure looks like the following:
/pages
/index.js
/city.js
I've created a custom server so that if the user goes to anything other than the home page it should render city.js. For example if you go to myapp.com/phl then the url should stay myapp.com/phl but it should render city.js. The same applies if you go to myapp.com/stl.
Here's my custom server:
const express = require('express');
const next = require('next');
const url = require('url');
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handler = app.getRequestHandler();
app.prepare()
.then(() => {
const server = express();
server.get('*', (request, response) => {
return handler(request, response);
});
server.get('/:airportCode', (request, response) => {
console.log('hello from the server');
app.render( request, response, '/city', { ...request.query, ...request.params } );
});
server.listen(3000, error => {
if (error) throw error;
console.log('> Ready on http://localhost:3000');
});
})
.catch(exception => {
console.error(exception.stack);
process.exit(1);
});
When I visit the home page it renders that page fine, but when I go to https://myapp.com/phl I get a 404. Am I missing something?
You need to switch up your page handler with the asterisk page handler:
const express = require('express');
const next = require('next');
const url = require('url');
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handler = app.getRequestHandler();
app.prepare()
.then(() => {
const server = express();
server.get('/:airportCode', (request, response) => {
console.log('hello from the server');
app.render( request, response, '/city', { ...request.query, ...request.params } );
});
server.get('*', (request, response) => {
return handler(request, response);
});
server.listen(3000, error => {
if (error) throw error;
console.log('> Ready on http://localhost:3000');
});
})
.catch(exception => {
console.error(exception.stack);
process.exit(1);
});
The function of asterisk is like a fallback for any path that isn't handled by the previous function.

Next.JS Hot Reload SSR

I'm doing development on Next.JS, and every time I hot reload after making a modification of the codes, there seems to be some kind of a cache that causes Client side codes and Server side codes to be different.
Currently, I need to open a new window every time I save my codes, in order to see the updates.
Is there anything I can do so it auto reload to the latest codes available all the time?
I tried using helmet/nocache with no results.
const express = require('express')
const next = require('next')
//const routes = require('./routes')
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
const nocache = require('nocache') //added no cache
app.prepare()
.then(() => {
const server = express()
server.use(nocache()) //using no cache
server.get('/listing/:id', (req, res) => {
const actualPage = '/listing'
const queryParams = { id: req.params.id }
return app.render(req, res, actualPage, queryParams)
})
server.get('*', (req, res) => {
return handle(req, res)
})
server.listen(3000, '127.0.0.2', (err) => {
if (err) throw err
console.log('> Ready on http://localhost:3000')
})
})
.catch((ex) => {
console.error(ex.stack)
process.exit(1)
})

Resources