Vite react axios frontend

New terminal at highest level Npm create vite@latest Install package Project name : frontend React framework Javascript +swc Cd frontend Npm install npm run dev This will load the default site Then install the dependencies we will use npm install @emotion/react @emotion/styled @hookform/resolvers \ @mui/icons-material @mui/material axios react react-dom \ react-hook-form react-router-dom yup npm install -D @types/react @types/react-dom \ @vitejs/plugin-react-swc eslint eslint-plugin-react \ eslint-plugin-react-hooks eslint-plugin-react-refresh vite You can add tailwind css if you like Clean up index.css in src so it looks like this :root { font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; } html, body{ height: 100%; margin: 0; padding: 0; } Main.jsx should look like this import React from 'react' import ReactDOM from 'react-dom/client' import App from './App.jsx' import './index.css' import {BrowserRouter as Router} from 'react-router-dom' ReactDOM.createRoot(document.getElementById('root')).render( ) App.jsx should look like this import { useState } from 'react' import './App.css' import Home from './components/Home' import Register from './components/Register' import Login from './components/Login' import About from './components/About' import Navbar from './components/Navbar' import {Routes, Route, useLocation} from 'react-router-dom' import ProtectedRoute from './components/ProtectedRoutes' import PasswordResetRequest from './components/PasswordResetRequest' import PasswordReset from './components/PasswordReset' function App() { const location = useLocation() const noNavbar = location.pathname === "/register" || location.pathname === "/" || location.pathname.includes("password") return ( { noNavbar ? : } ) } export default App If your not using tailwind at the moment app.css could look like this .myBackground{ width:100vw; height: 100vh; display: flex; align-items: center; justify-content: center; background: rgb(205,0,118); background: linear-gradient(137deg, rgba(205,0,118,1) 0%, rgba(85,35,185,1) 68%); } .whiteBox{ background-color: white; padding: 20px; min-width: 300px; height: 70%; width: 25%; border: 1px solid #333; } .itemBox{ display: flex; justify-content: center; align-items: center; width: 100%; height: 80px; } .title{ font-size: 30px; color: #333; } .myForm, .myButton{ width: 100%; } .myButton{ background: rgb(66, 8, 160) !important; } Also make sure your .eslintrc.cjs looks like this module.exports = { root: true, env: { browser: true, es2020: true }, extends: [ 'eslint:recommended', 'plugin:react/recommended', 'plugin:react/jsx-runtime', 'plugin:react-hooks/recommended', ], ignorePatterns: ['dist', '.eslintrc.cjs'], parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, settings: { react: { version: '18.2' } }, plugins: ['react-refresh'], rules: { 'react-refresh/only-export-components': [ 'warn', { allowConstantExport: true }, ], }, } Then in your src folder create a new folder components We are going to create our pages first About.jsx const About = () =>{ return( This is the about page ) } export default About Home.jsx import AxiosInstance from './AxiosInstance' import {React, useEffect, useMemo, useState} from 'react' import {Box} from '@mui/material' const Home = () =>{ const [myData, setMyData] = useState() const [loading,setLoading] = useState(true) const GetData = () => { AxiosInstance.get(`users/`).then((res) =>{ setMyData(res.data) console.log(res.data) setLoading(false) }) } useEffect(() =>{ GetData(); },[]) return( { loading ? Loading data... : {myData.map((item, index) => ( ID: {item.id} Email: {item.email} ) )} } ) } export default Home Login.jsx import '../App.css' import {React, useState} from 'react' import { Box } from '@mui/material' import MyTextField from './forms/MyTextField' import MyPassField from './forms/MyPassField' import MyButton from './forms/MyButton' import {Link} from 'react-router-dom' import {useForm} from 'react-hook-form' import AxiosInstance from './AxiosInstance' import { useNavigate } from 'react-router-dom' import MyMessage from './Message' const Login = () =>{ const navigate = useNavigate() const {handleSubmit, control} = useForm() const [ShowMessage, setShowMe

Mar 13, 2025 - 19:02
 0
Vite react axios frontend

New terminal at highest level
Npm create vite@latest
Install package
Project name : frontend
React framework
Javascript +swc
Cd frontend
Npm install
npm run dev

This will load the default site

Then install the dependencies we will use

npm install @emotion/react @emotion/styled @hookform/resolvers \ @mui/icons-material @mui/material axios react react-dom \ react-hook-form react-router-dom yup

npm install -D @types/react @types/react-dom \
  @vitejs/plugin-react-swc eslint eslint-plugin-react \
  eslint-plugin-react-hooks eslint-plugin-react-refresh vite

You can add tailwind css if you like

Clean up index.css in src so it looks like this


:root {
  font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
}


html, body{
  height: 100%;
  margin: 0;
  padding: 0;
}


Main.jsx should look like this

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import './index.css'
import {BrowserRouter as Router} from 'react-router-dom'


ReactDOM.createRoot(document.getElementById('root')).render(
  
      
         
     
  


)

App.jsx should look like this

import { useState } from 'react'
import './App.css'
import Home from './components/Home'
import Register from './components/Register'
import Login from './components/Login'
import About from './components/About'
import Navbar from './components/Navbar'
import {Routes, Route, useLocation} from 'react-router-dom'
import ProtectedRoute from './components/ProtectedRoutes'
import PasswordResetRequest from './components/PasswordResetRequest'
import PasswordReset from './components/PasswordReset'


function App() {
  const location = useLocation()
  const noNavbar = location.pathname === "/register" || location.pathname === "/" || location.pathname.includes("password")


  return (
    <>
      {
        noNavbar ?
        
            }/>
            }/>
            }/>
            }/>
        


        :


        
            }>
                }/>
                }/>
            
          


        }
      />
      }
    
  )
}


export default App

If your not using tailwind at the moment app.css could look like this

.myBackground{
  width:100vw;
  height: 100vh;
  display: flex;
  align-items: center;


  justify-content: center;
  background: rgb(205,0,118);
  background: linear-gradient(137deg, rgba(205,0,118,1) 0%, rgba(85,35,185,1) 68%);
}


.whiteBox{
  background-color: white;
  padding: 20px;
  min-width: 300px;
  height: 70%;
  width: 25%;
  border: 1px solid #333;
}


.itemBox{
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 80px;
}


.title{
  font-size: 30px;
  color: #333;
}


.myForm,
.myButton{
  width: 100%;
}


.myButton{
  background: rgb(66, 8, 160) !important;
}

Also make sure your .eslintrc.cjs looks like this

module.exports = {
  root: true,
  env: { browser: true, es2020: true },
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
    'plugin:react/jsx-runtime',
    'plugin:react-hooks/recommended',
  ],
  ignorePatterns: ['dist', '.eslintrc.cjs'],
  parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
  settings: { react: { version: '18.2' } },
  plugins: ['react-refresh'],
  rules: {
    'react-refresh/only-export-components': [
      'warn',
      { allowConstantExport: true },
    ],
  },
}

Then in your src folder create a new folder components

We are going to create our pages first

About.jsx

const About = () =>{
    return(
        
This is the about page
) } export default About

Home.jsx

import AxiosInstance from './AxiosInstance'
import {React, useEffect, useMemo, useState} from 'react'
import {Box} from '@mui/material'


const Home = () =>{


    const [myData, setMyData] = useState()
    const [loading,setLoading] = useState(true)


    const GetData = () => {
        AxiosInstance.get(`users/`).then((res) =>{
            setMyData(res.data)
            console.log(res.data)
            setLoading(false)
        })
    }


    useEffect(() =>{
        GetData();
    },[])


    return(
        
{ loading ?

Loading data... :

{myData.map((item, index) => (
ID: {item.id}
Email: {item.email}
) )}
}
) } export default Home

Login.jsx

import '../App.css'
import {React, useState} from 'react'
import { Box } from '@mui/material'
import MyTextField from './forms/MyTextField'
import MyPassField from './forms/MyPassField'
import MyButton from './forms/MyButton'
import {Link} from 'react-router-dom'
import {useForm} from 'react-hook-form'
import AxiosInstance from './AxiosInstance'
import { useNavigate } from 'react-router-dom'
import MyMessage from './Message'


const Login = () =>{
    const navigate = useNavigate()
    const {handleSubmit, control} = useForm()
    const [ShowMessage, setShowMessage] = useState(false)


    const submission = (data) => {
        AxiosInstance.post(`login/`,{
            email: data.email,
            password: data.password,
        })


        .then((response) => {
            console.log(response)
            localStorage.setItem('Token', response.data.token)
            navigate(`/home`)
        })
        .catch((error) => {
            setShowMessage(true)
            console.error('Error during login', error)
        })
    }



    return(
        
{ShowMessage ? : null}
Login for Auth App No account yet? Please register! Password forgotten? Click here
) } export default Login

Register.jsx

import '../App.css'
import { Box } from '@mui/material'
import MyTextField from './forms/MyTextField'
import MyPassField from './forms/MyPassField'
import MyButton from './forms/MyButton'
import {Link} from 'react-router-dom'
import {useForm} from 'react-hook-form'
import AxiosInstance from './AxiosInstance'
import { useNavigate } from 'react-router-dom'
import {yupResolver} from "@hookform/resolvers/yup"
import * as yup from "yup"




const Register = () =>{
    const navigate = useNavigate()


    const schema = yup
    .object({
        email: yup.string().email('Field expects an email adress').required('Email is a required field'),
        password: yup.string()
                    .required('Password is a required field')
                    .min(8,'Password must be at least 8 characters')
                    .matches(/[A-Z]/,'Password must contain at least one uppercase letter')
                    .matches(/[a-z]/,'Password must contain at least one lower case letter')
                    .matches(/[0-9]/,'Password must contain at least one number')
                    .matches(/[!@#$%^&*(),.?":;{}|<>+]/, 'Password must contain at least one special character'),
        password2: yup.string().required('Password confirmation is a required field')
                     .oneOf([yup.ref('password'),null], 'Passwords must match')


    })  


    const {handleSubmit, control} = useForm({resolver: yupResolver(schema)})


    const submission = (data) => {
        AxiosInstance.post(`register/`,{
            email: data.email,
            password: data.password,
        })


        .then(() => {
            navigate(`/`)
        }
        )
    }


    return(
        
User registration Already registered? Please login!
) } export default Register

Now were going to make our page components

Message.jsx

import { Box } from "@mui/material"




const MyMessage = ({text, color}) =>{
    return(
        
            {text}
        
    )
}


export default MyMessage

Navbar.jsx


import * as React from 'react';
import Box from '@mui/material/Box';
import Drawer from '@mui/material/Drawer';
import AppBar from '@mui/material/AppBar';
import CssBaseline from '@mui/material/CssBaseline';
import Toolbar from '@mui/material/Toolbar';
import List from '@mui/material/List';
import Typography from '@mui/material/Typography';
import ListItem from '@mui/material/ListItem';
import ListItemButton from '@mui/material/ListItemButton';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import InboxIcon from '@mui/icons-material/MoveToInbox';
import HomeIcon from '@mui/icons-material/Home';
import InfoIcon from '@mui/icons-material/Info';
import {Link, useLocation} from 'react-router-dom'
import LogoutIcon from '@mui/icons-material/Logout';
import AxiosInstance from './AxiosInstance';
import { useNavigate } from 'react-router-dom';


const drawerWidth = 240;


export default function Navbar(props) {
  const {content} = props
  const location = useLocation()
  const path = location.pathname
  const navigate = useNavigate()


  const logoutUser = () =>{
     AxiosInstance.post(`logoutall/`,{
     })
     .then( () => {
        localStorage.removeItem("Token")
        navigate('/')
     }


     )
  }


  return (
    
      
       theme.zIndex.drawer + 1 }}>
        
          
            Clipped drawer
          
        
      
      
        
        
          

              
                
                  
                        
                  
                  
                
              


              
              
                  
                        
                  
                  
                
              


              
              
                  
                        
                  
                  
                
              

          

        
      
      
        
            {content}
      
    
  );
}

Most importantly is our axios instance that connects our frontend and backend

import axios from 'axios'


const baseUrl = 'http://127.0.0.1:8000/'


const AxiosInstance = axios.create({
    baseURL: baseUrl,
    timeout: 5000,
    headers:{
        "Content-Type":"application/json",
         accept: "application/json"
    }
})


AxiosInstance.interceptors.request.use(
    (config) => {
        const token = localStorage.getItem('Token')
        if(token){
            config.headers.Authorization = `Token ${token}`
        }
        else{
            config.headers.Authorization = ``
        }
        return config;
    }
)


AxiosInstance.interceptors.response.use(
    (response) => {
        return response
    },
    (error) => {
        if(error.response && error.response.status === 401){
            localStorage.removeItem('Token')
        }


    }
)


export default AxiosInstance;

Then our PasswordReset page

import '../App.css'
import {React, useState} from 'react'
import { Box } from '@mui/material'
import MyTextField from './forms/MyTextField'
import MyPassField from './forms/MyPassField'
import MyButton from './forms/MyButton'
import {useParams } from 'react-router-dom'
import {useForm} from 'react-hook-form'
import AxiosInstance from './AxiosInstance'
import { useNavigate } from 'react-router-dom'
import MyMessage from './Message'


const PasswordReset = () =>{
    const navigate = useNavigate()
    const {handleSubmit, control} = useForm()
    const {token} = useParams()
    console.log(token)
    const [ShowMessage, setShowMessage] = useState(false)




    const submission = (data) => {
        AxiosInstance.post(`api/password_reset/confirm/`,{
            password: data.password,
            token: token,
        })


        .then((response) => {
            setShowMessage(true)
            setTimeout(() =>{
                navigate('/')
            }, 6000 )
        })

    }
    return(
        
{ShowMessage ? : null}
Reset password
) } export default PasswordReset
Password reset request 

import '../App.css'
import {React, useState} from 'react'
import { Box } from '@mui/material'
import MyTextField from './forms/MyTextField'
import MyPassField from './forms/MyPassField'
import MyButton from './forms/MyButton'
import {Link} from 'react-router-dom'
import {useForm} from 'react-hook-form'
import AxiosInstance from './AxiosInstance'
import { useNavigate } from 'react-router-dom'
import MyMessage from './Message'


const PasswordResetRequest = () =>{
    const navigate = useNavigate()
    const {handleSubmit, control} = useForm()


    const [ShowMessage, setShowMessage] = useState(false)




    const submission = (data) => {
        AxiosInstance.post(`api/password_reset/`,{
            email: data.email,
        })


        .then((response) => {
            setShowMessage(true)
        })

    }
    return(
        
{ShowMessage ? : null}
Request password reset
) } export default PasswordResetRequest

Protected routes

import {Outlet, Navigate} from 'react-router-dom'


const ProtectedRoute = () => {
    const token = localStorage.getItem('Token')


    return(


        token ?  : 
    )


}


export default ProtectedRoute

In the components folder create a new folder called forms

Create a file called MyButton.jsx

import * as React from 'react';
import Button from '@mui/material/Button';


export default function MyButton(props) {
  const {label,type} = props
  return (
      

MyPassField.jsx

import * as React from 'react';
import IconButton from '@mui/material/IconButton';
import OutlinedInput from '@mui/material/OutlinedInput';
import InputLabel from '@mui/material/InputLabel';
import InputAdornment from '@mui/material/InputAdornment';
import FormControl from '@mui/material/FormControl';
import Visibility from '@mui/icons-material/Visibility';
import VisibilityOff from '@mui/icons-material/VisibilityOff';
import { FormHelperText } from '@mui/material';
import {Controller} from 'react-hook-form'


export default function MyPassField(props) {
  const [showPassword, setShowPassword] = React.useState(false);
  const {label,name, control} = props


  const handleClickShowPassword = () => setShowPassword((show) => !show);


  const handleMouseDownPassword = (event) => {
    event.preventDefault();
  };


  return (
    (


          
          {label}
          
                
                  {showPassword ?  : }
                
              
            }
            label={label}
          />


         {error?.message} 


        



    )
  }

 />



  );
}

MyTextField.jsx

import * as React from 'react';
import '../../App.css'
import TextField from '@mui/material/TextField';
import {Controller} from 'react-hook-form'


export default function MyTextField(props) {
  const {label, name, control} = props
  return (


     (


          

        )
      }

     />


  );
}

And there you have it django react log in

To run it use python manage.py runserver on the backend and rpm run dev on frontend

);
}

MyPassField.jsx
import * as React from 'react';
import IconButton from '@mui/material/IconButton';
import OutlinedInput from '@mui/material/OutlinedInput';
import InputLabel from '@mui/material/InputLabel';
import InputAdornment from '@mui/material/InputAdornment';
import FormControl from '@mui/material/FormControl';
import Visibility from '@mui/icons-material/Visibility';
import VisibilityOff from '@mui/icons-material/VisibilityOff';
import { FormHelperText } from '@mui/material';
import {Controller} from 'react-hook-form'

export default function MyPassField(props) {
const [showPassword, setShowPassword] = React.useState(false);
const {label,name, control} = props

const handleClickShowPassword = () => setShowPassword((show) => !show);

const handleMouseDownPassword = (event) => {
event.preventDefault();
};

return (
name = {name}
control = {control}
render = {({
field:{onChange, value},
fieldState : {error},
formState,
}) =>(

      
      {label}
      
            
              {showPassword ?  : }
            
          
        }
        label={label}
      />


     {error?.message} 


    



)

}

/>

);
}

MyTextField.jsx

import * as React from 'react';
import '../../App.css'
import TextField from '@mui/material/TextField';
import {Controller} from 'react-hook-form'

export default function MyTextField(props) {
const {label, name, control} = props
return (

 (


      

    )
  }

 />

);
}

And there you have it django react log in

To run it use python manage.py runserver on the backend and rpm run dev on frontend