How to list all pages in a path? - reactjs

I have a structure like this:
pages:
- route1
- lots of js page
- index.js
I would like to display a list of all pages under route1 on my index page.
How can I fetch all available pages?
I tried to use getStaticProps in index to load all the files using fs and path but I am not able to require all the pages.
export async function fetchPages() {
const fs = require('fs')
const path = require('path')
const files = fs.readdirSync(path.join(process.cwd(), '/pages/route1/'))
return map(files, (f) => {
return require(path.join(process.cwd(), '/pages/route1/', f))
})
}
but this is not working.
Edit: require is used to load all the export from those pages such as title of the page or excerpt to display on the index page.
Edit: The error is Error: Cannot find module '/path/to/pages/route1/pageName.js'. Coming from the require.
Edit: I tried to use How to generate a menu based on the files in the pages directory in Next.js but it does not work since in the next config file we have to use require/module.export but the require('path/to/page') is going to bring react pages with imports and exports

Can you create a page variable as an Array and push routes ?
const fs = require('fs')
const path = require('path')
const pages = []
const files = fs.readdirSync(path.join(process.cwd(), '/pages/route1/'))
files.forEach((file) => {
pages.push(require(path.join(process.cwd(), '/pages/route1/', file)))
})
return pages

Related

NextJS dynamimc routing question about slugs

I have a doubt with nextjs..
I'm building my site like this
pages
[slug]
index.jsx
index.jsx
so in my slug/index I'm doing this
export async function getStaticPaths() {
const resProducts = await fetch(`${process.env.PRIVATE_ENDPOINT}/products`);
const products = await resProducts.json();
const paths = products.data.map((p) => ({
params: {
slugProduct: p.slug,
},
}));
return {
// this should be dynamic
paths,
fallback: true,
};
}
My question is what happend if I add a new product in my back office?
Do I have to rebuild with next build?
My question is what happend if I add a new product in my back office?
Do I have to rebuild with next build?
The short answer is NO. If the requested page have not been genereted at build time, Next.js will serve a "fallback" version of the page and will statically generate the requested path HTML and JSON on the background. When the statically generation completed, the browser receives the JSON for the generated path. Subsequent requests to the same path will serve the generated page, just like other pages pre-rendered at build time.
Don't forget to use router.isFallback to detect that request is on fallback.
You can see the good document here.
https://nextjs.org/docs/basic-features/data-fetching#getstaticpaths-static-generation

Images not loading unless I rebuild App Next JS

I am having trouble with images lately in next js. I know next has deprecated support for static in favour of public directory. So even after refactoring, I still cant get images to load. Here is the flow:
I choose an image for a project and send an axios request to the server. The server only saves the path to mongodb like this:
staticPath = `/ProjectImages/projImg_${req.decodedTokenData.userId}_${_id}_${key}.png`;
let imagePath = path.normalize(__dirname + `/../../public${staticPath}`);
dbImages.push(staticPath);
and writes the image's base64encoded value to a file and saves it to ProjectImages directory in public dir.
Now when I create a project, the images doesnt load even though it has reference to the path and the image itself is in the correct place. Only after rebuilding the app do I see the image.
Note: this issue does not occur in development mode only in production.
please help.!
Masla he koi ni
rather than calling the images from source directly i would recommend you to create a route and serve all those images from there
const express = require("express");
const router = express.Router();
const path = require('path');
const fs = require('fs');
router.get('/media/project/:path',function (req,res,next) {
const _path = `/static/ProjectImages/${req.params.path}`;
let imagePath = path.normalize(__dirname + `/../../public${_path}`);
try{
if (fs.existsSync(imagePath)) {
res.sendFile(imagePath);
}else{
res.sendStatus(404);
}
}catch (err) {
res.sendStatus(404);
}
});

How to use Dynamic Routing to trigger the same .js in pages?

I have multiple routes for e.g:
/solutions/
/solutions/web-development/
/features/
/features/flexbox/
/plugins/
/plugins/permalink/
and so on.
I would like to run the same file (abc.js) for all of these routes. I have checked the Dynamic Routing Section of Next.js but according to that section, My understanding is that I need to create multiple directories and copy the same file on multiple instances.
Is there any way by which I can run the single file for all the DEFINED routes or for the whole site?
EDIT: I know that there is a way to do that by creating Custom Server and manually add dynamic routes BUT I am looking to achieve this without the creation of the external server.
I have found a way to tackle this thing. This can be done using the next.config.js file. The only thing which you needed is the page URLs and then you can apply the same file or even add conditions to apply using multiple files.
Here is the sample code:
module.exports = {
exportPathMap: async function(
defaultPathMap,
{ dev, dir, outDir, distDir, buildId }
) {
const paths = {};
const pageURLs = [
'/solutions/',
'/solutions/web-development/',
'/features/',
'/features/flexbox/',
'/plugins/',
'/plugins/permalink/'
];
var loopInit = 0;
var loopCount = pageURLs.length;
var url = '';
for (loopInit = 0; loopInit < loopCount; loopInit += 1) {
url = pageURLs[loopInit];
switch(url) {
case '/solutions/':
paths[`${url}`] = {
page: '/solutions',
query: {
slug: url
}
};
break;
case '/features/':
paths[`${url}`] = {
page: '/features',
query: {
slug: url
}
};
break;
default:
paths[`${url}`] = {
page: '/',
query: {
slug: url
}
};
break;
}
}
return paths;
},
exportTrailingSlash: true
};
In the above example, I have hardcoded the URLs in pageURLs variable. You can pass dynamic values in it like get Permalinks from WordPress, URL Alias from Drupal or from any other CMS or Headless CMS, etc.
In the switch case, I am applying different templates on /solutions/ and /features/. For the remaining URLs, I am applying a single template.
NOTE: page: '/' refers index.js under pages directory similarly, page: '/solutions' refers solutions.js under pages directory and so on. It can be changed/vary as per developer choice.
I have tested this solution on the 9.1.4 version of Next.js. Please refer to the Next.js documentation for further details.
https://nextjs.org/docs#custom-configuration
https://nextjs.org/docs#usage
EDITED: This solution works for both server-side rendering and Next.js export.

create react app Configuration file after build app

I want a Config File (JSON) in root folder after build to config my app.
like Translation and API Urls and ...
Can I do this with create react app?
Create config.js or json file outside src directory and include it in index.html like
<script src="%PUBLIC_URL%/config.js" type="text/javascript"></script>
configure parameters in config.js
config.js
var BASE_URL = "http://YOUR-URL";
you can get paramenters like
const BASE_URL = window.BASE_URL;
You can store you JSON file in the public/ folder and it'll automatically provide this file when you host your Create React App.
Something like: /public/my-configuration-file.json
then when you restart your application:
localhost:3000/my-configuration-file.json
will provide you this json file.
You could create a custom hook that reads a "public" config file using fetch.
// This path is relative to root, e.g. http://localhost/config.json
const configFile = './config.json'
export function useConfig() {
const [config, setConfig] = useState(initialConfig);
useEffect(() => {
(async function fetchConfig() {
try {
const response = await (await fetch(configFile)).json();
setConfig(response);
} catch (e) {
console.log(e);
}
}());
}, []);
return config;
}
Then use it anywhere in you app
function App() {
const config = useConfig();
return (
<div>{config.foo}</div>
);
}
You'll always have an up to date non-cached version of it's data.
updating this topic with a brand new package that is available now that brings the joys of .Net Configuration to the JavaScript world: wj-config.
This package is pretty much an exact answer to what you need. Read this blog post for more information.
It is incredible to me how during over 6 years nobody filled in this gap in React (and JavaScript in general). Anyway, give wj-config a try. I think it will be a positive experience.

Koa.js serve React, api url also render with React page in Chrome

I'm using koa-static to serve static file with root url localhost:3000/, and koa-router to serve RESTful api, like localhost:3000/api/account/login
Make a fakeBuild folder contain only one file index.html. All work fine. root url and api url show correct content.
// serve static file
const serve = require('koa-static')
const staticPath = path.join(__dirname,'..','Client','poker','fakeBuild')
log(staticPath)
app.use(serve(staticPath))
// router
const router = require('./router/Index.js')(app)
Then I try to connect Koa with React
I use yarn build to build React static files, React project is created by create-react-app, not modified.
Then I change the koa-static's target to build folder, just one line changed
const staticPath = path.join(__dirname,'..','Client','poker','build')
Then access localhost:3000/, chrome show React start page, works
Then access localhost:3000/api/account/login, chrome show React start page, what??
Use postman check localhost:3000/api/account/login, it response what I put in router, fine.
So I can use apis, just ignore chrome's result?
It must be React and Chrome doing something extra. I try to remove service-worker.js in React build folder, api url render correctly in chrome.
So anyone can give some documents or explain to help me understand what react done, to keep all the url render it.
And why my api localhost:3000/api/account/login not require service-worker.js (just return some text in response body), also got the js worked. Just because koa-static served the file?
====
Update: my router code, And project available on here
router/Index.js
const Router = require('koa-router');
const R = (app)=>{
const router = new Router();
const api = require('./Api.js');
router.use('/api', api.routes(), api.allowedMethods())
app.use(router.routes())
.use(router.allowedMethods());
};
module.exports = R;
router/Api.js
const Router = require('koa-router')
const log = require('../helper/Utils').log;
module.exports = (function () {
const Api = new Router();
Api.get('/account/login', async (ctx, next)=>{
log("hello");
ctx.status = 200;
ctx.body = `login`
});
Api.get('/account/register', async (ctx, next)=>{
ctx.status = 200;
ctx.body = `register`
});
return Api;
})();

Resources