Git Product home page Git Product logo

nextjs-starter's Introduction

๐Ÿšจ This project is now archived

This project is now archived and is no longer maintained.

I'm happy so many people found this project useful, but it's now out of date and many of the features of this starter project are now redundant as Next.js has evolved considerably over the last few years and now has native support for features such as CSS and SASS and for API routes without requiring a custom server.

For that reason I'm retiring this project and putting it into archive mode.

Thank you to everyone who contributed to this project over the last 3 years!

Where to look for examples


Next.js Starter Project

This is a starter project for React that uses Next.js.

  • Authentication via Email, Facebook, Twitter and Google+
  • Uses Express combined with Passport JS for authentication and route handling
  • Account management - Update details, link/unlink accounts, delete account
  • Session support with secure HTTP Only cookies and CSRF Tokens
  • SASS/SCSS wth Bootstrap 4 and Reactstrap with Bootstrap components for React
  • Comes with Ionicons icon font and shows how to bundle other CSS and font files

You can see a live demo at https://nextjs-starter.now.sh

About

Next.js is a framework that makes it easy to create 'universal' React apps - React apps that do both client and server side rendering.

With Next.js, React pages are automatically rendered on both client and server side, without the hassle of setting up dependancies like webpack or babel and with automatic routing and without the constraints of projects like Create React App.

This is a starter project that provides an example of how to use Next.js with Express, SASS/SCSS, Bootstrap, Reactstrap (Boostrap 4 for React), the Ionicons icon set, examples of how to include data from remote REST APIs and incorporate an authentication system that supports both oAuth and Email using Passport (a popular authentication framework for Node.js).

This project exists to make it easier to get started a creating production app in React. You are invited to use it as a reference or to copy it and use it as a base for your own projects. Contributions to improve this project are welcome.

Running locally in development mode

To get started, just clone the repository and run npm install && npm run dev:

git clone https://github.com/iaincollins/nextjs-starter.git
npm install
npm run dev

Note: If you are running on Windows run install --noptional flag (i.e. npm install --no-optional) which will skip installing fsevents.

Building and deploying in production

If you wanted to run this site in production, you should install modules then build the site with npm run build and run it with npm start:

npm install
npm run build
npm start

You should run npm run build again any time you make changes to the site.

Note: If you are already running a webserver on port 80 (e.g. Macs usually have the Apache webserver running on port 80) you can still start the example in production mode by passing a different port as an Environment Variable when starting (e.g. PORT=3000 npm start).

Configuring

If you configure a .env file (just copy .env.example over to '.env' and fill in the options) you can configure a range of options.

See the AUTHENTICATION.md for how to set up oAuth if you want to do that. It suggested you start with Twitter as it's the easiest to get working.

Deploying to the cloud with now.sh

To deploy to production on Zeit's now.sh cloud platform you will need to install the Now desktop app on your computer. If you don't want to install the Now desktop app, you can use the following command to install it (either approach is fine):

sudo npm i -g --unsafe-perm now

Once installed, open now.json and set a name and alias for your site.

To deploy, just run now in the working directory:

npm install -g now
now

If you configure a .env file now will include it when deploying if you use the -E option to deploy:

now -E

If you want to have your local .env file have variables for local development and have a different sent of variables you use in production, you can create additional .env files and tell now to use a specific file when deploying:

now -E production.env

After deploying

Once you have deployed, now will return a URL where the site when it has been deployed to, you can use this to preview everything works correctly in the browser.

If you have set an alias for the site, you can then make the site live on the alias you have defined using now alias:

now alias

By default, this will point any aliases you have set in now.json to your site.

You can configure now to use aliases with custom domains using the now domain and now dns commands.


Further reading

Database hosting

If you need an instance of MongoDB in the cloud https://mlab.com/ have free and inexpensive options.

Secrets for Environment Variables

Once you are comfortable using .env files for configuration and running and deploying your app, take a look at now secrets to set options in the cloud so you don't have to set them each time you deploy.

GitHub integration

You can integrate now with a GitHub account to trigger automated deployments anytime you push to GitHub. This works great if you have secrets set up!

Now 2.0

When you deploy this project you will see this message as of November 2018:

WARN! You are using an old version of the Now Platform. More: https://zeit.co/docs/v1-upgrade

Now 2.0 was released in November 2018 and works differently from Now 1.0. This project has not been updated for Now 2.0. You may ignore this message for now.

Alternate hosting options

You can host your Next.js site with any hosting provider. Although it works great on Now, it also works great with other providers like Heroku, Amazon Web Service, Google Cloud Platform, Microsoft Azure, DigitalOcean and others.

nextjs-starter's People

Contributors

bennygenel avatar bookercodes avatar captdaylight avatar ddrager avatar efallancy avatar frederickfogerty avatar handtrix avatar iaincollins avatar jt3k avatar patte avatar pungggi avatar timweprovide avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nextjs-starter's Issues

Incorrect sign in/sign out status in Internet Explorer

Sometimes pages render with stale data in Internet Explorer - I have seen showing a user appearing as as signed in after they have signed out, due to Internet Explorer displaying a previously rendered page view with them signed in while navigating around the site.

I'm not sure if this is a problem with the session logic (such as something that tells the client to flush the session data from localStorage) or if something about Internet Explorer incorrectly caching pages and displaying old versions from memory.

I'm not seeing this issue in other browsers, but might be worth digging into to see how serious the problem is (i.e. if it's something that could be addressed in Next.js or if it's just something specific to this project).

Update to Next.js 4.x and React 16

Currently this project uses reactstrap, which has React 15 dependancies, so the project is still on Next.js 3.x (which uses React 15).

Either I'd like to refactor the project not to use reactstrap and just use CSS and className properties on HTML elements (the modal for the sign in pop up and the profile would be the most work, but every template would probably need to be touched).

Alternatively, it would be great if reactstrap was updated to support React 16, but I have no idea how much work is involved in doing that.

Pull requests to address either of these (i.e. either to reactstrap or to this project) would be amazing.

Trouble adapting

I'm attempting to adapt this into two versions since I can't use ORM2 (it can't seem to connect to mLab):
1 - a version that uses mongoose, and
2 - a version that uses sequelize

The sequelize version will probably be easier for me since it's similar to ORM, but I'm having major trouble figuring out how to incorporate mongoose.

Is there anything you can suggest as a pointer? I've been using this post as a guide but there's just enough difference to make things difficult (for me anyway).

I thank you for coming up with this. I think you've done a great job.

I was hoping to get my code ship-shape and plan to submit it to the Next.js examples since I know a lot of node devs like MongoDB/mongoose for NoSQL, and sequelize for relational DBs.

XMLHttpRequest is not defined

Something strange happened to me: suddenly I get an error from the session component, "XMLHttpRequest is not defined". When I added global.XMLHttpRequest = require ("xmlhttprequest");
Back to the file, I get another error: These modules were not found:

  • child_process in ./node_modules/xmlhttprequest/lib/XMLHttpRequest.js
  • fs in ./node_modules/xmlhttprequest/lib/XMLHttpRequest.js

Setting Metadata / Title

Thanks for the quick overview on how next.js 2.0 works together with the server with this starter repo.

I was just playing around with it and couldn't get it to work with react-helmet on the server.js and was wondering if it was possible with the current configuration. Any input would be great - since I'm still learning how next works, thanks!

Edit: I suppose that I can add the 'next/head' and mess with it in the <Head></Head>, but is there a more native solution to add react-helmet?

Update "async.js" page to render quicker when loaded by client router

Add a check to getInitialProps() in async.js to see if we are rendering client side and if so to instead use componentDidMount() (which is called on initial page load but not on subsequent page loads) and componentWillReceiveProps() (which is called if props change) and this.state (instead of this.props) to store the remotely fetched data.

A constructor() call which calls this.setState() will also be needed, so this.state is populated from this.props when being run on the server.

The purpose of this is to start rendering the page quicker on the client by displaying the page as quickly as possible, before we have all the data - and to highlight the difference between componentDidMount() and componentWillReceiveProps() as that is a bit of a gotcha.

Error handling for client-side routing

Just discovered your project today and it is awesome. Thank you for putting it together!

I noticed that the error page does not show up if the user is routed to an invalid page client-side. Seems to work if I remove the custom error page.

Redirect Error and null email processed

Hi,
Good starter template for next.js, but I see there are some problems. First one is that, without entering any email on the input in route /auth/signin it processed to next page with the success message.
Second one is redirect doesn't work on the post request via ajax. So I don't see why you're adding this line on the page.
https://github.com/iaincollins/nextjs-starter/blob/master/routes/auth.js#L119
There are other issues as well like opening multiple route for getting csrf token.
I hope you resolved these issues.

Internet Explorer compatibility problems

There is an incompatibility issue with (even recent) versions of Internet Explorer and some pages.

Not all pages are impacted but at least some pages cause a problem and do not load properly if loaded client side. The CSS page seems to cause a problem, though I can't think what would triggering a bug on that page as the only unique thing about it is that it invokes next/head and has inline CSS with JSX.

There are no known issues with Chrome, Firefox or Safari across desktop or mobile.

Support Passport

I notice that you temporary remove it. Do close this when you bring it back just to notify me. :)

Thanks

Secure path example

I was trying to figure out how would a path that needs authentication would work with this approach. For instance, if there's an admin area /admin/*, how could all that path get protected by the nextjs-starter approach?

Refactor Session component to use unfetch

The session component (components/session.js) currently uses XMLHttpRequest to handle POST and GET requests. I would like to change this to use unfetch instead of XMLHttpRequest.

It uses XMLHttpRequest and not fetch because it has the browser send CSRF and HTTP Only sessions cookies along with each request - and fetch does not currently read or send HTTP Only cookies by design.

However unfetch is a 'work-a-like' of fetch that actually uses XMLHttpRequest under the hood so it behaves like fetch from a user perspective but sends cookies like XMLHttpRequest (it's super small and actually just wraps XMLHttpRequest in a Promise).

There wouldn't be any functionality gain from doing this, re-writing the Session component to use unfetch would just clean up and reduce the code in session.js and make it a bit easier to read.

Note: The Profile page already uses unfetch to to handle GET and POST requests for user data, so we are already using unfetch in the project.

Alternative JWT auth mechanism?

In the thread at vercel/next.js#153 @trandainhan has created a nice JWT implementation.

https://github.com/trandainhan/next.js-example-authentication-with-jwt

It's not suitable for some of the use cases I have - where I need the server to be able to store a Refresh Token from places like Google+ to do operations in the background - but it's a lot less convoluted if you don't need to store data server side or don't want to have to maintain a separate session database.

It's obviously potentially faster and certainly cheaper to scale - and perfect for static websites. With JWT encrypted token payloads are small enough they could all be stored on the server.

To maintain CSRF support without sessions, we'd have to migrate to migrate to an approach like the Double Submit Cookie method (where a CSRF token is created in a cookie and in a value submitted along with each POST request):

https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet#Double_Submit_Cookie

If I add this it would be potentially much simpler and in theory there could still be the option to save user profiles to a database (using optional callbacks).

Facebook oAuth not working properly and causing crash

Somehow the oauth login is not working properly on live anymore with Facebook.

  • Facebook oauth does not seem to be supplying an email address anymore.
  • nextjs-starter is accepting a blank email address and saving the value as empty (replacing a temporary twitter oauth based email if there is one) when linking to an account that was created by signing in Twitter.
  • The blank email address value is then causing a crash somewhere else in the app when trying to link to a Google account or unlink then relink to a Twitter account (now.sh restarts the instance shortly after but the server goes down briefly).

This is a relatively new issue, previously working behaviour and may be as a result of a Facebook change or a bug introduced by refactoring.

Add Bootstrap 4 support?

Considering adding Bootstrap 4 to make it easier for folks to actually build on top of. It's still alpha, but it has been for the longest time so version 3 seems a bit backwards at this point.

Feedback is welcome, let me know if you think this would be helpful - and I could extend it with a few pages, maybe even a secure, universal account management page - or if you think it would complicate the example.

Note: Currently it doesn't use any CSS frameworks, just a 'main.scss' file with about 125 lines for minimal formatting.

Production Mode - Building

The instructions didn't work for me, I had to run npm run build instead of npm build in order to get it to work.

How to protect routes?

First, thanks for putting this together. It looks very much like what I need (and what I was about 1/3 of the way through putting together).

I do have one question, though. I didn't see any examples in the project of how to protect a route from access by unauthenticated users. Maybe I overlooked it?

I've tried a couple of things, mostly around checking the props.session value in various methods (constructor, render, getInitialProps) of the page component. These work, but there's an annoying flicker as the page is rendered and then the router is redirected to the /auth/signin page. I could do some conditional rendering (eg. an unauthorized message) if the user is not authorized, but there's still going to be that moment where the message is rendered and then the transition is made to the new page.

Thanks for your help!

Periodically check sessions have not expired

As of 2.4.0 (specifically an update in 2.3.7) calling Session.getSession() on the client causes it to store a copy of the session in window.session so it can track globally if it has been loaded by the current application already.

The first call to Session.getSession() looks for window.session and if it is not populated then it gets the latest session state information from the server. This prevents the client from appearing to still be logged after going back to the site with a potentially stale/expired session.

This works reasonably well, but is not ideal as browser windows left open for a long period of time could still end up displaying as if a user was logged in even after the session on the server had expired. Closing and re-opening (or refreshing) the browser window or tab does cause the state to update however, as it triggers resetting the state of window.session.

Ideally, the session object returned by the server from "/session" would contain an "expires" or "maxAge" value which we could use to determine when the client should next check the session expiry time.

This could alternatively be an option in the Session class on the client, but encouraging people to set it one place (the server) have it propagate to the client (rather than having to worry about having different session expiry thresholds on the server and client) seems like a good idea.

Some sort of alternate maxAge or keepAlive value might be preferable to an 'expires' value to prevent waiting until a session has actually expired before re-validating it.

nextjs development env session created for each request (on-demand-entries type request)

Hi,

I'm running your nextjs starter example in development mode, and i assume many requests are triggered due to dev mode and hot reloading. Requests such as http://localhost:3000/_next/on-demand-entries-ping?page=/

For each request such as this a new session is created, and /tmp/sessions easily gets filled with alot of session files.
Have you encountered this issue? Is there any way to avoid creating new sessions for each nextjs ping request?

Update Session component to add Redux Store and use connect()

The Session component works perfectly fine, well am considering refactoring it in a more typical React/Redux pragma by using a Store as a practical usage example.

The Clock demo that's included (from the official wiki) uses a Store and connect() but it's not the easiest (or most re-useable) example to follow.

I can't see a huge practical benefit from the point of view of application behaviour and I'm not sure if this would make the logic easier to follow, more bloated, or even make the logic harder to follow, but it's an established pragma so seems worth considering.

(I already use a Store with connect() for session handling in another project, I'm just not quite sure the pragma is justified over using more easily readable vanilla JS for the same thing).

I am also tempted to set up an event handler to listen for events on the session store and/or fire server events showing how that if you perform an action (like sign in or out) in one tab/window that it can automatically update other tabs/windows.

Comments/suggestions around this welcome.

CSRF token mismatch using connect-pg-simple

Thanks for iterating upon the latest version of next. It's nice to see the changes through your project.

I've actually been using an older committed version of this repo version and can't seem to get other types of compatible session stores to work.

For example, changing the store from FileStore to https://www.npmjs.com/package/connect-pg-simple seems to always bring up CSRF mismatch, and I'm not quite sure where to start looking to come to a solution.

Any direction or help would be appreciated!
Thanks

Improvements to pages/auth/signin.js

Improve the componentDidMount() call in pages/auth/signin.js.

Avoid calling setState() in it if possible to avoid re-renders that at not really necessary and definitely don't call this.state directly, that's a typo.

It should look something like this:

  async componentDidMount() {
    const session = new Session()
    const latestSessionData = await session.getSession(true)
  }

The render() function may need to be changed to reference this.props rather than this.state.

Review and make improvements for accessibility

This starter project should set a better example by being more accessible.

Fixes for issues issues are most welcome.

Raising bugs for specific accessibility issues is also very welcome.

PropTypes Error on live demo and local testing

Hi, I've noticed this on my console.

app.js:3 Uncaught TypeError: Cannot read property 'PropTypes' of undefined at Object.o.23.113 (app.js:3) at a (app.js:3) at app.js:3 at Object.o.38.113 (app.js:3) at a (app.js:3) at app.js:3 at Object.o.31.10 (app.js:3) at a (app.js:3) at app.js:3 at Object.o.47.1 (app.js:3)

Add documentation page explaining and link to security tips

This should be addd as a page linked to on the left hand nav.

It should explain:

  • How the authentication system works (using HTTP Only cookies and what they are).
  • How the CSRF system we are using works.
  • How the express session middleware works.
  • What alternative approaches are for authentication (e.g. JWT) and advantages/disadvantages.

If anyone would like to have a go at this, please feel free!

Not getting emails (being blocked)

The demo doesn't use a mail server, it just connects to port 25 of the recipients server and tries sending a message. This is now being blocked it looks like (and was never reliable or a good idea, as always likely to be dropped).

It's designed to be easy to configure a mail transport as an option; I might add support for reading it from an environment variable and then configure it to use my Google account or some other mail service for the demo so folks can try it out before downloading.

In the meantime be aware that the online demo doesn't work for email; but if you run it locally (and/or configure the 'mailserver' option - see routes/auth.js) then it should be fine.

Return to the URL of the page the user was in after signing in

Instead of just directing to the profile page, we want to save the URL of the current page in a callback URL so that after a user is bounced to an oAuth service (or clicks a link in email) they are directed back to the page they were on after being signed in.

A good way to do this would be to create a route like /auth/callback which loads the session into the client before doing a redirection.

We'd want to do something like Base 64 encode the current URL as a param and preserve any query string parameters.

"Link Accounts" option does not render correctly server side

The "Link Accounts" option - that is displayed on the profile page when a user is signed in - does not show linked accounts when rendered with server side rendering.

This should be updated to show how to achieve the same functionality rendering both client and server side pages. There are multiple different ways to achieve this.

running production fails

Dev mode works great.
I can push the app to Now.
running production locally crashes.

npm run build ... then

nextjs-starter git:(master) โœ— npm run start

[email protected] start /Users/paul/projects/nextjs-starter
node index.js

events.js:161
throw er; // Unhandled 'error' event
^

Error: listen EACCES 0.0.0.0:80
at Object.exports._errnoException (util.js:1023:11)
at exports._exceptionWithHostPort (util.js:1046:20)
at Server._listen2 (net.js:1248:19)
at listen (net.js:1297:10)
at Server.listen (net.js:1375:9)
at Function.listen (/Users/paul/projects/nextjs-starter/node_modules/express/lib/application.js:617:24)
at app.prepare.then.then.db (/Users/paul/projects/nextjs-starter/index.js:116:10)

npm ERR! Darwin 16.4.0
npm ERR! argv "/Users/paul/.nvm/versions/node/v7.5.0/bin/node" "/Users/paul/.nvm/versions/node/v7.5.0/bin/npm" "run" "start"
npm ERR! node v7.5.0
npm ERR! npm v4.1.2
npm ERR! code ELIFECYCLE
npm ERR! [email protected] start: node index.js
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script 'node index.js'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the nextjs-starter package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node index.js
npm ERR! You can get information on how to open an issue for this project with:
npm ERR! npm bugs nextjs-starter
npm ERR! Or if that isn't available, you can get their info via:
npm ERR! npm owner ls nextjs-starter
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR! /Users/paul/projects/nextjs-starter/npm-debug.log
โžœ nextjs-starter git:(master) โœ—

Reactstrap 5.x Dropdowns do not work correctly

They don't render correctly on mobile, and they don't work without JavaScript enabled on the client.

These are both issues with Reactstrap. The former is likely to be fixed in updates to Reactstrap 5.x alpha, but the latter will require additional work if we want to resolve that.

As the site supports universal rendering and sessions I'd like to resolve the issue with navigation.

Improvements to passport-strategies.js

I've got some improvement to passport-strategies.js which I should include.

The improvements include:

  • An option to easily specify what the 'id' field should be when serialising/deserialising user objects.

In the case of using a Mongo DB, for example, you would want to set this to _id, but for an SQL DB (including SQL LITE) it would be id (which is the currently hard coded value).

I'd expected the default User.get() method created by the ORM lib to handle this automatically, but it doesn't.

  • The option to specify an absolute path for the callback URL.

This is a security enhancement to force redirects after authenticating with oAuth to redirect to a secure HTTPS URL.

By default services may redirect to a HTTP URL, even if you have come from an HTTPS URL. The current behaviour exposes one time use only session token in the clear when the user is bounced back after authorising access.

Expand CSS/SCSS documentation

The CSS/SCSS documentation could be expanded - maybe even split off into a separate page from the layout documentation - with more useful examples as well as some discussion about how you might want to use a CDN to serve CSS if you have a lot of third party JS/CSS libraries, especially if initial page loading performance is an issue.

Question: Session storage on server/client

Firstly, thank you for a great starter project!

With your Session.js component implementation the current session is either retrieved from the server (via req) or the client (via localStorage).

How are these two kept in sync? For example I believe if there is a valid session on the server and localStorage is empty, an XHR request is made to the server to get the session (and set localStorage). However what happens if the server session is lost (deleted cookies etc) but localStorage still exists?

The initial page load would show an empty session (not logged in via req) but client side routing will show as a valid session being present (logged in via localStorage).

It this scenario unlikely and not to be concerned about?

npm run dev issue

MacOS, i cloned the repo and did npm i. Then I tried to run it:


bash-3.2$ npm run dev

> [email protected] dev /Volumes/EXFAT-1Tb/Work/nextjs-study-starter
> NODE_ENV=development PORT=3000 node index.js

/Volumes/EXFAT-1Tb/Work/nextjs-study-starter/routes/auth.js:22
exports.configure = ({
                     ^

ReferenceError: Invalid left-hand side in assignment
    at exports.runInThisContext (vm.js:53:16)

Node.js version is 4.7.3.
Why it dont want to run?

Provide examples of an isometric store

The goal is to show how to create a simple store, that supports with universal rendering.

Redux is the common approach taken for this, and unlike MobX it doesn't require decorator support, but Redux generally requires more code to do the same thing and is not always as easy to follow the logic.

There was a previous example of a Clock that use Redux and supported server side rendering but it wasn't a great introductory example and didn't cover a use case that translated well for most people so I removed it.

I'm considering adding a store that uses MobX to the project, as in the below example, but I appreciate more people would probably like a Redux example (in this case the same working example in both would be ideal!).

What's missing from the below example is meaningful Server Side Rendering support. The store allows a default value to be passed in (e.g. from a session) but it would make sense if there was a flow that could read directly from the server when a store was rendering on the server.

Maybe I need to shortlist some real use cases to come up with a meaningful practical example. Ideas for practical examples of stores welcome!

Most of the use cases I have in production (in real world projects) are fetching data from REST APIS and I find simple JavaScript classes are simpler to implement and use (and less code!), especially in conjunction with Web Storage APIs to cache data.

I think the only place I actually bother with a Store in production is to use socket.io with React in a graceful way, to avoid creating a new Socket and to track when events happen on a Socket.

Note: I considered making the Session component a Store as an example, but like a lot of other cases I have it would have added complexity and code for little to no benefit so decided against it.

Config required to use mobx with Next.js (as it relies on decorators) in .babelrc:

{
"presets": [
    "next/babel"
  ],
  "plugins": ["transform-decorators-legacy"]
}

Code for a Counter store in stores/counter.js:

import { observable, action } from 'mobx'

let store = null

class Store {
  @observable counter = 0
  
  // Initalize store with default values if passed any
  constructor ({
      counter = 0
    }) {
    this.counter = counter
  }

  @action
  increment () {
    this.counter++
  }

  @action 
  decrement () {
    this.counter--
  }

  @action
  startAutoInc () {
    this.timer = setInterval(() => { 
      this.counter++
    }, 1000)
  }

  @action
  stopAutoInc () {
    clearInterval(this.timer)
    this.timer = null
  } 

  @action 
  autoIncIsRunning () {
    return (this.timer) ? true : false;
  }
  
  @action
  resetCounter () {
    this.counter = 0
  }
}

export function initStore(defaults = {}) {
  if (typeof window === 'undefined') {
    return new Store(defaults)
  } else {
    if (store === null) {
      store = new Store(defaults)
    }
    return store
  }
}

Code for a component using the Counter store in components/counter.js:

import React from 'react'
import { observer } from 'mobx-react'
import { Store, initStore } from '../stores/counter'

@observer
export default class extends React.Component {

  constructor(props) {
    super(props)
    this.store = initStore(this.props.store) // Default value defined in props
    this.handleStartStop = this.handleStartStop.bind(this)
  }

  handleStartStop () {
    this.store.autoIncIsRunning() ? this.store.stopAutoInc() : this.store.startAutoInc()
  }

  render () {
    return (
      <div>
        <div className='counter'>
          <span>{this.store.counter}</span>
        </div>
        <div className='buttons'>
          <button onClick={() => this.store.increment()}>Increment</button>
          <button onClick={() => this.store.decrement()}>Decrement</button>
          <button onClick={this.handleStartStop}>{this.store.autoIncIsRunning() ? 'Stop' : 'Start'} Auto-increment</button>
          <button onClick={() => this.store.resetCounter()}> Reset</button>
        </div>
        <style jsx>{`
        .counter {
          background: black;
          color: white;
          padding: 20px;
          text-align: center;
        }
      `}</style>
      </div>
    )
  }
}

Separate authentication server

Hi and thanks again for this helpful project ๐Ÿ™‚

Currently the authentication API is mixed with the next.js frontend server. For a production app these would need to be separated. Do you plan to do that?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.