I'm using a custom server.js for routing which uses something like this:
app.prepare().then(() => {
createServer((req, res) => {
const parsedUrl = parse(req.url, true);
const rootStaticFiles = ['/robots.txt', '/sitemap.xml', '/favicon.ico'];
if (rootStaticFiles.indexOf(parsedUrl.pathname) > -1) {
const path = join(__dirname, 'static', parsedUrl.pathname);
app.serveStatic(req, res, path);
} else {
handler(req, res);
}
}).listen(3000);
});
And when I run it, there's this warning about the 'url' property, but I don't know ho to resolve it. It seems to me that withRouter doesn't apply here. Could someone help please?
Okay, it looks like they solved it with one of the updates. It does not appear anymore.
Related
I want to integrate my NextJS application with Windows Active Directory; I have searched a lot but didn't find good articles to explain that.
I tried to use the node-expose-sspi module but struggled with how to integrate it into the application.
In a normal express app the usage is like this:
const express = require("express")
const { sso } = require("node-expose-sspi")
app.use(sso.auth())
app.get('/sso', (req, res) => {
console.log(req.sso)
return res.end()
})
I couldn't get any success with API middleware; could anyone help with that, so I could be able to use it in my NextJS app without creating a custom server?
Also please let me know if there is a better way to integrate with active directory other than node-expose-sspi.
I managed to handle it like that:
const { sso } = require("node-expose-sspi")
const ssoAuth = sso.auth(ssoOptions)
export default async function handler(req, res) {
return new Promise((resolve, reject) => {
try {
return ssoAuth(req, res, () => {
res.json({ sso: req.sso })
resolve()
})
} catch (error) {
reject(error)
}
})
}
We recently locked to node version 14.19.1 to maintain a stable version across environments. But after this, The below functionality is not working without deleting the lock file and rebuilding it.
Router.replace is not working without dropping the lock file and generating a new one.
import { useEffect } from 'react'
import { useRouter } from 'next/router'
export const useIfUnsavedChanges = (unsavedChanges, callback) => {
const Router = useRouter()
useEffect(() => {
if (unsavedChanges) {
const routeChangeStart = (url) => {
if (Router.asPath !== url ) {
const confirm = callback()
sessionStorage.setItem('nextRoute',url)
if (!confirm) {
Router.events.emit('routeChangeError')
Router.replace(Router, Router.asPath, { shallow: true })
throw 'Abort route change. Please ignore this error.'
}
}
}
Router.events.on('routeChangeStart', routeChangeStart)
return () => {
Router.events.off('routeChangeStart', routeChangeStart)
}
}
}, [unsavedChanges])
}
--------- package-lock.json------------------------------------------------------------
Sharing the CodeSandbox link for the lock file. I have been stuck for more than a week to identify the issue. I have line by line compared the lock file and tried to update the version in lock file to test but still no luck.
https://codesandbox.io/s/nice-raman-6mjx68?file=/package-lock.json
Okay, I build Game DB schema using astronomy package in meteor.
Then I try to add method to it by extending it in server. (server/gamehandle.js)
import {Game} from '../imports/db/game'
import {DDP} from 'meteor/ddp-client'
Game.extend({
meteorMethods: {
AddNewGame(judul){
const invocation = DDP._CurrentInvocation.get()
this.namaGame = judul
this.creator = invocation.userId
this.createdAt = new Date()
return this.save()
}
}
})
But when I try to run the method in app client using callMethod it throw an error that astronomy/execute not found 404.
This the component using it
import {Game} from '../../../db/game'
export function NewGameList(props){
const { isOpen, onOpen, onClose } = useDisclosure()
const [judul, setJudul] = useState('')
const [hasil, setHasil] = useState(null)
const judulChange = (e) => setJudul(e.target.value)
const AddGame = new Game()
const handleSubmit = (e) => {
e.preventDefault()
AddGame.callMethod('AddNewGame', judul, (err, result) => {
result ? setHasil(result) : setHasil(err.message)
console.log(err)
})
}
...
So enlight me, what thing I do wrong?
Finally found the solution from meteor slack.
Just need to imports my db file to main js file in server.
I am trying to set up a next.js app, but I'm having trouble handling routes with a trailing slash. So, for example, if I have a pages structure like this:
pages
- index.js
- blog
- index.js
- [slug].js
then going to / gives me the base index.js, going to /blog gives me blog/index.js, and going to /blog/my-post gives me blog/[slug].js — so far so good.
But going to /blog/ gives me a 404 error, and there appears to be no way at all to handle this without entirely replacing the next.js router—I can't even redirect /blog/ to /blog. Is there any way around this, or do I need a custom router? Is there a way to extend the next.js router in a way that will let me handle these, without entirely replacing it?
There is an option with Next.js 9.5 and up.
In next.config.js, add the trailingSlash config:
module.exports = {
trailingSlash: true,
}
Source: Trailing Slash
UPDATE: If you are using next export than you can solve the issue by adding exportTrailingSlash to your next.config.js
As of this writing, there seems to be no way to solve this issue without defining your own custom server.
Previous answer:
You must create a new file blog.js shown bellow:
With the following server.js
const express = require('express')
const next = require('next')
const PORT = process.env.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('/blog', (req, res) => {
const actualPage = '/blog'
// const queryParams = { title: req.params.id }
app.render(req, res, '/blog', {})
})
server.get('/blog/:id', (req, res) => {
const actualPage = '/blog/[id]'
const queryParams = { title: req.params.id }
app.render(req, res, actualPage, queryParams)
})
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)
})
node server.js should start your server and you would have the mapping that you need.
Note, blog/index.js is not used in this example.
I don't have a solution to this. This is still a massive problem. However, I do have a very horrible hack that I've been using to workaround this problem in Next.js 9.x.x
In my /pages/_error.js I've added the following code:
FourOhFour.getInitialProps = ({asPath, res}: any): any => {
if (asPath.endsWith('/')) {
res.writeHead(301, {Location: asPath.substring(0, asPath.length - 1)});
return res.end();
}
return {};
};
This will ensure that all routes that end with a trailing slash are redirected to the non-trailing slash path via a 301 redirect.
I`ve done that redirect by using nginx for my production app:
rewrite ^(.+)/+$ $1 permanent;
You can add this to your _app.js file
MyApp.getInitialProps = async ctx => {
const pathAndQueryDivided = ctx.ctx.req.url.split('?');
if (pathAndQueryDivided[0].endsWith('/')) {
const urlWithoutEndingSlash = pathAndQueryDivided[0].replace(/\/*$/gim, '');
ctx.ctx.res.writeHead(301, {
Location: urlWithoutEndingSlash + (pathAndQueryDivided.length > 1 ? `?${pathAndQueryDivided[1]}` : ''),
});
ctx.ctx.res.end();
return {};
}
const initialProps = await App.getInitialProps(ctx);
return {
...initialProps,
};
};
App.getInitialProps gets called first server-side
It divides splits the path and the query params because we only want to know if the url ends with a slash
It asks if the url ends with a slash
It replaces the last slash of the url with nothing
It redirects you to the url without the slash + the query params if there's any
-component
---->sidebar.js
---->exampleTabOne.js
---->exampleTabTwo.js
---->exampleTabThree.js
--pages
---->setting(which include all sidebar and those exampletabs)
i do've above folder structure in my nextJS project.
here as per nextjs doc
on localhost/setting i can easily view my page
but what i want to achieve is something like below:
1.localhost/setting/exampleTabOne
2.localhost/setting/exampleTabTwo/EXAMPLEID
3.localhost/setting/exampleTabThree/EXAMPLEID#something#something
the last part Url with # is something like inside tab content i ve another tabs so i want to fix it with Hash url so that while ssr i can easily open that inside tab too..
So, will you guys please suggest me how to solve this?
Here , In Next JS, We can achieve this by defining in server.js file.
// This file doesn't go through babel or webpack transformation.
// Make sure the syntax and sources this file requires are compatible with the current node version you are running
// See https://github.com/zeit/next.js/issues/1245 for discussions on Universal Webpack or universal Babel
const { createServer } = require('http');
const { parse } = require('url');
const next = require('next');
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
app.prepare().then(() => {
createServer((req, res) => {
// Be sure to pass `true` as the second argument to `url.parse`.
// This tells it to parse the query portion of the URL.
const parsedUrl = parse(req.url, true);
const { pathname, query } = parsedUrl;
if (pathname === '/setting/exampleTabOne') {
app.render(req, res, '/setting', query);
} else if (pathname === '/setting/exampleTabTwo/EXAMPLEID') {
app.render(req, res, '/setting', query);
} else {
handle(req, res, parsedUrl);
}
}).listen(3000, err => {
if (err) throw err;
console.log('> Ready on http://localhost:3000');
});
});
Where In setting page we can dynamically load the respective component watching url pathname.