title
Protected Routes in React using React Router
description
In this video, we will create a protected route using React Router. This route is accessible only when the user is logged in.
Link to CodeSandbox: https://codesandbox.io/s/ol6z72kjy9
Tutorial from Nick Karnik. Check out his YouTube channel: https://www.youtube.com/channel/UClCm-WAOgN6XLwCpefSVezg
Nick on Twitter: https://twitter.com/theoutlander
--
Learn to code for free and get a developer job: https://www.freecodecamp.org
Read hundreds of articles on programming: https://medium.freecodecamp.org
detail
{'title': 'Protected Routes in React using React Router', 'heatmap': [{'end': 240.483, 'start': 221.836, 'weight': 1}], 'summary': 'Tutorial series on react router covers the implementation of public and protected routes, user authentication, restructuring, and best practices for specifying routes, protecting components, and ensuring smooth transitions between protected and public pages.', 'chapters': [{'end': 369.641, 'segs': [{'end': 28.05, 'src': 'embed', 'start': 0.269, 'weight': 0, 'content': [{'end': 4.234, 'text': "Hey, this is Nick Carnick, and you're watching Practical Examples in React.", 'start': 0.269, 'duration': 3.965}, {'end': 10.841, 'text': "Today, we're going to implement public and protected routes using React Router.", 'start': 6.036, 'duration': 4.805}, {'end': 13.404, 'text': "Let's dive into some code.", 'start': 11.922, 'duration': 1.482}, {'end': 18.489, 'text': "We're running a basic React application here via codesandbox.io.", 'start': 14.405, 'duration': 4.084}, {'end': 28.05, 'text': 'All the React Router components used in a web application should be imported from React Router DOM.', 'start': 20.822, 'duration': 7.228}], 'summary': 'Nick carnick demonstrates the implementation of public and protected routes using react router, in a basic react application via codesandbox.io.', 'duration': 27.781, 'max_score': 0.269, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Y0-qdp-XBJg/pics/Y0-qdp-XBJg269.jpg'}, {'end': 148.18, 'src': 'embed', 'start': 71.77, 'weight': 1, 'content': [{'end': 82.699, 'text': "Going back to index, we're going to import our landing page from landing page.", 'start': 71.77, 'duration': 10.929}, {'end': 91.866, 'text': "And let's load the landing page right here.", 'start': 83.94, 'duration': 7.926}, {'end': 94.468, 'text': 'And notice that landing page prints right there.', 'start': 92.366, 'duration': 2.102}, {'end': 106.309, 'text': "Alright, next we're going to import BrowserRouter from react-router-dom.", 'start': 96.943, 'duration': 9.366}, {'end': 116.135, 'text': 'BrowserRouter basically gives access to the history API and keeps the UI in sync with the URL.', 'start': 107.93, 'duration': 8.205}, {'end': 121.058, 'text': 'Now we need to wrap our app component with BrowserRouter.', 'start': 116.856, 'duration': 4.202}, {'end': 123.44, 'text': "Let's go ahead and do that.", 'start': 122.319, 'duration': 1.121}, {'end': 126.142, 'text': 'All right, everything still works as expected.', 'start': 124.06, 'duration': 2.082}, {'end': 131.827, 'text': "Let's import route and switch from React Router DOM.", 'start': 126.702, 'duration': 5.125}, {'end': 136.631, 'text': "We're going to convert landing page to a route.", 'start': 132.767, 'duration': 3.864}, {'end': 139.233, 'text': "So let's remove landing page here.", 'start': 137.371, 'duration': 1.862}, {'end': 148.18, 'text': "We're going to create a route component and pass in landing page as a component reference to route.", 'start': 139.673, 'duration': 8.507}], 'summary': 'Import landing page and browserrouter, convert landing page to a route, and wrap app component with browserrouter.', 'duration': 76.41, 'max_score': 71.77, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Y0-qdp-XBJg/pics/Y0-qdp-XBJg71770.jpg'}, {'end': 204.043, 'src': 'embed', 'start': 173.188, 'weight': 4, 'content': [{'end': 181.353, 'text': "that's because it does a prefix match and so essentially it matches on slash here and still loads landing page.", 'start': 173.188, 'duration': 8.165}, {'end': 189.138, 'text': 'what we need to do is specify the exact property so that it only loads when the route is the route.', 'start': 181.353, 'duration': 7.785}, {'end': 200.401, 'text': "in this case, we're going to create a component called app layout, which will load when we specify the appRoute.", 'start': 189.138, 'duration': 11.263}, {'end': 204.043, 'text': "First, let's take care of returning a React component here.", 'start': 201.201, 'duration': 2.842}], 'summary': 'Implementing exact property for route match in react component.', 'duration': 30.855, 'max_score': 173.188, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Y0-qdp-XBJg/pics/Y0-qdp-XBJg173188.jpg'}, {'end': 249.151, 'src': 'heatmap', 'start': 221.836, 'weight': 1, 'content': [{'end': 225.659, 'text': "Let's call this appLayout.", 'start': 221.836, 'duration': 3.823}, {'end': 230.753, 'text': "And on save, it's going to reorder everything.", 'start': 228.511, 'duration': 2.242}, {'end': 240.483, 'text': "Now let's go back to index and we're going to import app layout from the app layout file.", 'start': 230.813, 'duration': 9.67}, {'end': 243.266, 'text': "And let's create another route here.", 'start': 241.444, 'duration': 1.822}, {'end': 249.151, 'text': "So if I copy and paste this, notice that we'll get two instances of landing page.", 'start': 243.586, 'duration': 5.565}], 'summary': 'The applayout app reorders content on save, creates a new route, and may produce duplicate landing pages.', 'duration': 27.315, 'max_score': 221.836, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Y0-qdp-XBJg/pics/Y0-qdp-XBJg221836.jpg'}, {'end': 302.553, 'src': 'embed', 'start': 265.402, 'weight': 5, 'content': [{'end': 269.445, 'text': "If I were to remove app here and go back to the root, it's going to show landing page.", 'start': 265.402, 'duration': 4.043}, {'end': 278.319, 'text': 'Now, what if we wanted to protect components under the app route and only make them available to users who were authenticated?', 'start': 270.393, 'duration': 7.926}, {'end': 287.525, 'text': "Before we can do this, let's create a file called auth.js to track the login status.", 'start': 279.239, 'duration': 8.286}, {'end': 294.851, 'text': 'This class will export an instance of the class.', 'start': 288.366, 'duration': 6.485}, {'end': 302.553, 'text': 'so that we mimic the singleton pattern.', 'start': 300.572, 'duration': 1.981}], 'summary': 'Creating auth.js to track login status for app route protection', 'duration': 37.151, 'max_score': 265.402, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Y0-qdp-XBJg/pics/Y0-qdp-XBJg265402.jpg'}], 'start': 0.269, 'title': 'React router implementation', 'summary': 'Covers the implementation of public and protected routes in a react application, including the importation of react router components, creation of a landing page component, incorporation of browserrouter, and best practices for specifying routes and protecting components based on url paths.', 'chapters': [{'end': 148.18, 'start': 0.269, 'title': 'Implementing public and protected routes in react', 'summary': 'Demonstrates implementing public and protected routes in a react application, covering the importation of react router components, creation of a landing page component, incorporating browserrouter to access the history api, and converting the landing page to a route.', 'duration': 147.911, 'highlights': ['The chapter covers implementing public and protected routes in a React application, focusing on the importation of React Router components, creation of a landing page component, and incorporating BrowserRouter to access the history API.', 'Demonstrates the process of importing React Router components and adding the dependency of React Router DOM to a basic React application via codesandbox.io.', 'Shows the creation of a component named landing page, which involves importing React, exporting landing page as a functional component, and returning markup within the component.', 'Explains the usage of BrowserRouter to provide access to the history API and keep the UI in sync with the URL, followed by wrapping the app component with BrowserRouter to ensure functionality.', 'Illustrates the conversion of the landing page to a route by importing route and switch from React Router DOM, and subsequently passing landing page as a component reference to route.']}, {'end': 369.641, 'start': 149.744, 'title': 'React routing best practices', 'summary': 'Explains how to specify routes and load components based on url paths in react, emphasizing the need to use the exact property to match routes, and demonstrating how to create a file to track login status for protecting components.', 'duration': 219.897, 'highlights': ['The chapter explains how to specify routes and load components based on URL paths in React, emphasizing the need to use the exact property to match routes. It emphasizes the importance of using the exact property to specify when a component should load based on the route, ensuring that it matches the exact path instead of just doing a prefix match.', 'The chapter demonstrates how to create a file to track login status for protecting components. It explains the creation of a file called auth.js to manage login status, including methods for login, logout, and checking if a user is authenticated, providing a foundational approach for managing authentication in a real-world scenario.']}], 'duration': 369.372, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Y0-qdp-XBJg/pics/Y0-qdp-XBJg269.jpg', 'highlights': ['Covers implementing public and protected routes in a React application, focusing on importing React Router components and incorporating BrowserRouter.', 'Explains the usage of BrowserRouter to provide access to the history API and keep the UI in sync with the URL.', 'Demonstrates the process of importing React Router components and adding the dependency of React Router DOM to a basic React application via codesandbox.io.', 'Illustrates the conversion of the landing page to a route by importing route and switch from React Router DOM.', 'Explains how to specify routes and load components based on URL paths in React, emphasizing the need to use the exact property to match routes.', 'Demonstrates creating a file to track login status for protecting components, including methods for login, logout, and checking if a user is authenticated.']}, {'end': 584.453, 'segs': [{'end': 442.687, 'src': 'embed', 'start': 369.661, 'weight': 1, 'content': [{'end': 377.963, 'text': 'So essentially you could be loading stuff from your local storage or the server side or look at your cookie, et cetera.', 'start': 369.661, 'duration': 8.302}, {'end': 386.146, 'text': "Let's go to our landing page and create a button for logging in.", 'start': 378.243, 'duration': 7.903}, {'end': 390.908, 'text': "So let's create a button here.", 'start': 389.648, 'duration': 1.26}, {'end': 409.857, 'text': "I'm gonna move this to an h1 tag and on click I would like to handle the callback right here.", 'start': 391.009, 'duration': 18.848}, {'end': 420.193, 'text': "Let's reference auth Now this is all lowercase because we're expecting an instance of the auth object.", 'start': 410.557, 'duration': 9.636}, {'end': 428.858, 'text': "We're going to call in, we're going to call auth.login with a callback method that gets triggered when login is successful.", 'start': 420.833, 'duration': 8.025}, {'end': 431.86, 'text': 'We want to redirect the user to the app.', 'start': 429.439, 'duration': 2.421}, {'end': 442.687, 'text': "So we're going to use a property called history and push the app route to it.", 'start': 432.601, 'duration': 10.086}], 'summary': 'Creating a login button on landing page with auth object method for successful login redirect.', 'duration': 73.026, 'max_score': 369.661, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Y0-qdp-XBJg/pics/Y0-qdp-XBJg369661.jpg'}, {'end': 516.977, 'src': 'embed', 'start': 474.246, 'weight': 0, 'content': [{'end': 479.411, 'text': "Although we're redirecting to app, we're not checking if the user is actually logged in.", 'start': 474.246, 'duration': 5.165}, {'end': 487.518, 'text': "So going back to index.js, we're going to create a new component called ProtectedRoute.", 'start': 480.432, 'duration': 7.086}, {'end': 499.729, 'text': 'And this component is going to import from React.', 'start': 494.304, 'duration': 5.425}, {'end': 516.977, 'text': "is going to import React from React and then we're simply going to export a constant called protected route, which is again a functional component,", 'start': 502.274, 'duration': 14.703}], 'summary': 'Creating protectedroute component for user authentication', 'duration': 42.731, 'max_score': 474.246, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Y0-qdp-XBJg/pics/Y0-qdp-XBJg474246.jpg'}], 'start': 369.661, 'title': 'React app authentication and protected route', 'summary': 'Covers implementing user authentication in a react app, including handling login callbacks, redirecting users to the app upon successful login, and creating a protected route to ensure users are authenticated before accessing certain pages.', 'chapters': [{'end': 584.453, 'start': 369.661, 'title': 'React app authentication and protected route', 'summary': 'Covers implementing user authentication in a react app, including handling login callbacks, redirecting users to the app upon successful login, and creating a protected route to ensure users are authenticated before accessing certain pages.', 'duration': 214.792, 'highlights': ['Creating a button for logging in on the landing page The chapter discusses creating a button for logging in on the landing page.', 'Handling the callback for login, using the auth object, and redirecting the user to the app upon successful login The chapter explains handling the callback for login, using the auth object, and redirecting the user to the app upon successful login.', 'Implementing a ProtectedRoute component to ensure users are authenticated before accessing certain pages The chapter demonstrates implementing a ProtectedRoute component to ensure users are authenticated before accessing certain pages.']}], 'duration': 214.792, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Y0-qdp-XBJg/pics/Y0-qdp-XBJg369661.jpg', 'highlights': ['Implementing a ProtectedRoute component to ensure users are authenticated before accessing certain pages', 'Handling the callback for login, using the auth object, and redirecting the user to the app upon successful login', 'Creating a button for logging in on the landing page']}, {'end': 936.933, 'segs': [{'end': 646.737, 'src': 'embed', 'start': 584.513, 'weight': 2, 'content': [{'end': 589.598, 'text': "I need to enclose this in brackets since we're destructuring or restructuring this now.", 'start': 584.513, 'duration': 5.085}, {'end': 592.321, 'text': "When I save, it's going to reorder everything.", 'start': 590.479, 'duration': 1.842}, {'end': 595.984, 'text': "Now let's go back to index.js.", 'start': 592.881, 'duration': 3.103}, {'end': 597.005, 'text': 'So far, everything loads.', 'start': 596.024, 'duration': 0.981}, {'end': 610.285, 'text': "Let's import our protected route from protected route, and we're going to copy that and simply replace this route here for app.", 'start': 597.365, 'duration': 12.92}, {'end': 611.886, 'text': "So let's save it.", 'start': 611.125, 'duration': 0.761}, {'end': 614.526, 'text': "So it's going to restructure everything so far.", 'start': 612.186, 'duration': 2.34}, {'end': 616.026, 'text': 'Everything seems to work.', 'start': 614.706, 'duration': 1.32}, {'end': 627.389, 'text': "Okay Now all protected route is doing is it's returning a route with the component that's passed in.", 'start': 616.106, 'duration': 11.283}, {'end': 629.909, 'text': "In our case, it's the app layout.", 'start': 628.269, 'duration': 1.64}, {'end': 632.524, 'text': 'as a render prop.', 'start': 631.483, 'duration': 1.041}, {'end': 635.947, 'text': 'We also need to check if the user is actually logged in.', 'start': 632.884, 'duration': 3.063}, {'end': 641.352, 'text': "So let's import auth from auth.", 'start': 636.488, 'duration': 4.864}, {'end': 646.737, 'text': "And inside of our function here, we're going to check if user is authenticated.", 'start': 642.313, 'duration': 4.424}], 'summary': 'Restructured and imported routes, confirmed authentication in app layout.', 'duration': 62.224, 'max_score': 584.513, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Y0-qdp-XBJg/pics/Y0-qdp-XBJg584513.jpg'}, {'end': 717.682, 'src': 'embed', 'start': 683.735, 'weight': 1, 'content': [{'end': 687.56, 'text': 'All this is available in the React Router documentation.', 'start': 683.735, 'duration': 3.825}, {'end': 692.067, 'text': "We're also going to pass a state.", 'start': 687.58, 'duration': 4.487}, {'end': 705.334, 'text': "prop to it or a value for its state which tells it that we're coming in from whatever location we were trying to go to,", 'start': 693.609, 'duration': 11.725}, {'end': 712.618, 'text': 'which will be passed in here through rest and then through props and finally down here.', 'start': 705.334, 'duration': 7.284}, {'end': 717.682, 'text': "So let's implement a logout button in the app layout.", 'start': 713.198, 'duration': 4.484}], 'summary': 'React router documentation contains instructions on passing state and implementing a logout button in the app layout.', 'duration': 33.947, 'max_score': 683.735, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Y0-qdp-XBJg/pics/Y0-qdp-XBJg683735.jpg'}, {'end': 825.123, 'src': 'embed', 'start': 796.233, 'weight': 0, 'content': [{'end': 810.578, 'text': 'And in that case, we would need to import with router from oops, from React Router DOM and then use that as a higher order component.', 'start': 796.233, 'duration': 14.345}, {'end': 812.479, 'text': "Let's go ahead and click log out.", 'start': 811.199, 'duration': 1.28}, {'end': 814.74, 'text': 'And we have an error here.', 'start': 813.579, 'duration': 1.161}, {'end': 816.7, 'text': 'And I made the same mistake here.', 'start': 815.04, 'duration': 1.66}, {'end': 819.481, 'text': "That's not because I normally work with classes.", 'start': 816.981, 'duration': 2.5}, {'end': 825.123, 'text': 'And for the purpose of this demo, I had decided to use functional components.', 'start': 820.062, 'duration': 5.061}], 'summary': 'Using functional components with react router dom for error handling.', 'duration': 28.89, 'max_score': 796.233, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Y0-qdp-XBJg/pics/Y0-qdp-XBJg796233.jpg'}], 'start': 584.513, 'title': 'Reactjs restructuring, authentication, and router implementation', 'summary': 'Covers restructuring and authentication in reactjs, including importing and replacing components, implementing user authentication, logout button implementation with react router, passing state prop, utilizing history object, and handling routes and errors for smooth transitions between protected and public pages.', 'chapters': [{'end': 682.313, 'start': 584.513, 'title': 'Reactjs: restructuring and authentication', 'summary': 'Covers restructuring in reactjs by importing and replacing components, as well as implementing user authentication by checking if the user is logged in and redirecting accordingly.', 'duration': 97.8, 'highlights': ['The chapter delves into importing and replacing components in ReactJS through restructuring, ensuring everything loads and works properly.', "The process of user authentication is explained, including importing 'auth' from 'auth' and checking if the user is authenticated, returning a component if true and redirecting if false.", 'The concept of render prop in ReactJS is introduced, where the protected route returns a route with the component passed in, ensuring secure rendering based on user authentication.']}, {'end': 795.953, 'start': 683.735, 'title': 'React router implementation and logout button', 'summary': 'Discusses implementing a logout button in the app layout using react router, passing a state prop, and utilizing the history object to navigate, with emphasis on the availability of history via route and the callback upon successful logout.', 'duration': 112.218, 'highlights': ['The chapter discusses implementing a logout button in the app layout using React Router, passing a state prop, and utilizing the history object to navigate.', 'The availability of history on props is due to loading it via a route, allowing access to this.props.history.', 'Upon successful logout, a callback is executed to navigate back to the root using this.props.history.push.']}, {'end': 936.933, 'start': 796.233, 'title': 'React router handling', 'summary': 'Covers the implementation of react router for handling routes and errors, including importing higher-order components, defining routes, and using the switch statement, resulting in smooth transition between protected and public pages with the elimination of 404 errors.', 'duration': 140.7, 'highlights': ['The chapter covers the implementation of React Router for handling routes and errors, including importing higher-order components, defining routes, and using the switch statement, resulting in smooth transition between protected and public pages with the elimination of 404 errors.', "In the demonstration, it is shown that after implementing React Router, clicking 'log in' takes the user to the app layout, while clicking 'log out' directs the user back to the landing page, demonstrating successful route handling.", "The use of the switch statement in React Router ensures that only the first matching route is executed, effectively eliminating the appearance of the '404 not found' error, providing a seamless user experience."]}], 'duration': 352.42, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Y0-qdp-XBJg/pics/Y0-qdp-XBJg584513.jpg', 'highlights': ['The chapter covers the implementation of React Router for handling routes and errors, including importing higher-order components, defining routes, and using the switch statement, resulting in smooth transition between protected and public pages with the elimination of 404 errors.', 'The chapter discusses implementing a logout button in the app layout using React Router, passing a state prop, and utilizing the history object to navigate.', 'The concept of render prop in ReactJS is introduced, where the protected route returns a route with the component passed in, ensuring secure rendering based on user authentication.', "The process of user authentication is explained, including importing 'auth' from 'auth' and checking if the user is authenticated, returning a component if true and redirecting if false.", 'The chapter delves into importing and replacing components in ReactJS through restructuring, ensuring everything loads and works properly.']}], 'highlights': ['The chapter covers the implementation of React Router for handling routes and errors, including importing higher-order components, defining routes, and using the switch statement, resulting in smooth transition between protected and public pages with the elimination of 404 errors.', 'The concept of render prop in ReactJS is introduced, where the protected route returns a route with the component passed in, ensuring secure rendering based on user authentication.', "The process of user authentication is explained, including importing 'auth' from 'auth' and checking if the user is authenticated, returning a component if true and redirecting if false.", 'Handling the callback for login, using the auth object, and redirecting the user to the app upon successful login', 'Implementing a ProtectedRoute component to ensure users are authenticated before accessing certain pages', 'The chapter discusses implementing a logout button in the app layout using React Router, passing a state prop, and utilizing the history object to navigate.', 'Demonstrates creating a file to track login status for protecting components, including methods for login, logout, and checking if a user is authenticated.', 'Explains how to specify routes and load components based on URL paths in React, emphasizing the need to use the exact property to match routes.', 'Illustrates the conversion of the landing page to a route by importing route and switch from React Router DOM.', 'Explains the usage of BrowserRouter to provide access to the history API and keep the UI in sync with the URL.']}