__dirname is not defined within API routes - next.js

I have a Next.js API route which needs to access a local file, but __dirname is not defined when I use it within an API route.
Is it possible to get the current directory from within a Next route?

In order to access the root directory, or any directory for that matter, you can used next.config.js to set a webpack alias. Example:
// Inside next.config.js
module.exports = {
webpack: (config) => {
config.resolve.alias = {
...config.resolve.alias,
'~': __dirname,
};
}
Now ~, when used to path to resources, will resolve to the value of __dirname.
Alternatively you could use next.js's client env if you're on next.js 8+. Example:
// inside next.config.js
module.exports = {
env: {
ROOT: __dirname,
}
}
Now using process.env.ROOT gives you access to __dirname.

Related

Next js in subfolder /blog change index.js file for example to _blog_index.js?

in subfolder /blog can i change index.js file for example to _blog_index.js and it will be read as index.js?
each subfolder has index.js file and sometime is difficult to read in code editor, when i have many subfolders and many tabs open.
Thank u
This is possible when using rewrites() in next.config.js:
const nextConfig = {
async rewrites() {
return [
{
source: "/blog",
destination: "/blog/_blog_index",
},
];
},
};
module.exports = nextConfig;
However, keep in mind that rewrites() won't be supported if you're planning to export your app to static HTML because it requires a Node.js server.

Next Js: Middleware is ignored for a directory with re-writes

I have a file system like this
Pages
secure/
_middleware.ts
protectedResource.tsx
_app.tsx
_document.tsx
index.tsx
I have next configured like this
module.exports = {
...
async rewrites() {
return [
{
source: '/protectedResource',
destination: '/secure/protectedResource'
}
]
}
}
The rewrite works correctly, when accessing http://localhost:3000/protectedResource the user sees the correct route. The middleware from the 'secure' directory, however, is not invoked during the request pipeline. Aside from moving the middleware to the pages directory, how can I resolve this?

Exposing Storybook via NextJS route

I have a NextJS app and am using Storybook to develop my components.
After looking through all the NextJS routing documentation, I can't find a way to route to my storybook from within NextJS. Only access pages within the /pages directory.
What I would like to do it to have my StoryBook available at /styleguide from within my Next app thought all environments.
Is someone able to help?
Short answer: No, you can not do that.
But you can always redirect the url /styleguide to another domain where Storybook is running, for example styleguide.example.com. Here, an example based on the official documentation:
// next.config.js
module.exports = {
async redirects() {
return [
{
source: '/styleguide',
destination: 'https://styleguide.example.com',
permanent: true,
},
]
},
}
If your URL's would have any parameters for it's origin that you would want to append to the redirects destination, NextJS provides a feature to do just that.
// next.config.js
module.exports = {
async redirects() {
return [
{
source: '/styleguide/:pageId/:slug',
destination: 'https://styleguide.example.com/:pageId/:slug',
permanent: true,
},
]
},
}

Can I use env.js file instead of .env file to load environment variables using next.js in next.config.js file?

Can I use env.js file instead of .env file to load environment variables using next.js in next.config.js file ? If yes, can someone help with syntax with example code?
If you have an env.js file in your root folder that looks like this:
module.exports = {
MY_VARIABLE: 'value',
ANOTHER_VARIABLE: 'blah',
}
You can load them in next.config.js like this:
const path = require('path')
const webpack = require('webpack')
module.exports = {
webpack(config, options) {
const envObj = require(path.join(__dirname, 'env.js'))
const env = Object.keys(envObj).reduce((acc, name) => {
acc[`process.env.${name}`] = JSON.stringify(envObj[name])
return acc
}, {})
config.plugins.push(new webpack.DefinePlugin(env))
return config
},
}
Then in your app, you can access them as you would access environment variables in node (e.g. process.env.MY_VARIABLE). This works on the client side and the server side.

grunt-connect middleware for testing file uploads

How can I use grunt-connect with livereload to test uploading files to a server?
I'm using Yeoman and angular-seed for my project. One of the requirements is the ability to upload files to the server. Rather than setting up some external server for the project, I'd like to be able to keep everything contained in my current setup.
This solution adds middleware directly into Gruntfile.js for grunt-connect.
First it loads connect bodyParser which makes it easier to parse the uploaded file and form elements.
Next it sets an endpoint at '/upload'. This will be the route used during development and testing. This middleware returns a basic response with file properties.
Finally, the static routes that Yeoman automatically configures are appended to the list of middleware, which is returned back to grunt-connect.
Configuration property for adding a file upload handler to grunt-connect.
livereload: {
options: {
open: true,
base: [ '.tmp', '<%= yeoman.app %>' ],
middleware: function (connect, options) {
var middlewares = [
connect().use(connect.bodyParser({ uploadDir: '.tmp' })),
connect().use('/upload', function(req, res, next) {
/*
console.log(req.files); // files properties
console.log(req.body); // form properties
*/
res.setHeader('Content-Type', 'application/json');
// response with basic file stats
res.end(JSON.stringify({
'size': req.files.file.size,
'path' : req.files.file.path,
'other' : null }));
})
];
// add the static paths in options.base
options.base.forEach(function (base) {
middlewares.push(connect.static(base));
});
return middlewares;
}
}
}

Resources