Created
August 27, 2021 17:07
-
-
Save koolamusic/2e64184a033544d5297132211a497c6d to your computer and use it in GitHub Desktop.
Middleware and context example Nextjs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Adapted from: https://betterprogramming.pub/why-i-got-rid-of-getinitialprops-in-my-next-js-project-fc926e98ed61 | |
| export function authWrapper(next) { | |
| return async function auth(ctx) { | |
| const user = await session.getUser(); | |
| if (!user) { | |
| return { | |
| redirect: { | |
| destination: '/sign-in', | |
| permanent: false, | |
| }, | |
| }; | |
| } | |
| const props = { user }; | |
| return typeof next === 'function' ? next(ctx, props) : { props }; | |
| }; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // lib/compose.js | |
| // Pass middlewares as arguments to out composer | |
| export function compose(...middlewares) { | |
| // Return getServerSideProps handler | |
| return async function composer(ctx) { | |
| let prevIndex = -1; | |
| const pageProps = { props: {} }; | |
| // Create middlewares runner | |
| const runner = async (index) => { | |
| // Check if `next` was called accidently muliple times | |
| if (index === prevIndex) { | |
| throw new Error('next() was called multiple times'); | |
| } | |
| const middleware = middlewares[index]; | |
| prevIndex = index; | |
| if (typeof middleware === 'function') { | |
| // Run middlewares one by one | |
| await middleware(ctx, pageProps, () => { | |
| return runner(index + 1); | |
| }); | |
| } | |
| }; | |
| await runner(0); | |
| // Return results to next.js | |
| return pageProps; | |
| }; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Page.getInitialProps = ({ res }) => { | |
| if (res) { | |
| res.writeHead(307, { Location: '/path/to/target' }); | |
| res.end(); | |
| } | |
| Router.replace('/path/to/target'); | |
| return {}; | |
| }; | |
| export function getServerSideProps() { | |
| return { | |
| redirect: { | |
| destination: '/path/to/target', | |
| permanent: false, | |
| }, | |
| }; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // pages/profile.js | |
| import compose from 'lib/compose'; | |
| import session from 'lib/session'; | |
| import fetchArticles from 'data/articles'; | |
| import fetchFriends from 'data/friends'; | |
| import Profile from 'components/Profile'; | |
| import ArticlesList from 'components/ArticlesList'; | |
| import FriendsList from 'components/FriendsList'; | |
| export const getServerSideProps = compose(auth, getUserArticles, getUserFriends); | |
| export default function Profile({ user, articles, friends }) { | |
| return ( | |
| <main> | |
| <Profile user={user} /> | |
| <ArticlesList items={articles} /> | |
| <FriendsList items={friends} /> | |
| </main> | |
| ); | |
| } | |
| // Functions down below could be placed in diffrent files | |
| // And used for any pages where they could be needed | |
| async function auth(ctx, pageProps, next) { | |
| const currentSession = await session(ctx); | |
| if (!currentSession) { | |
| pageProps.redirect = { | |
| destination: '/sign-in', | |
| permanent: false, | |
| }; | |
| // Stop middlewares chain execution | |
| // because user not authorized to check this page | |
| return; | |
| } | |
| // Populate user to page props and continue middlewares execution | |
| pageProps.props.user = currentSession.user; | |
| return next(); | |
| } | |
| async function getUserArticles(ctx, pageProps, next) { | |
| pageProps.props.articles = await fetchArticles(ctx.req); | |
| return next(); | |
| } | |
| async function getUserFriends(ctx, pageProps, next) { | |
| pageProps.props.friends = await fetchFriends(ctx.req); | |
| return next(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment