diff --git a/src/frontend/src/components/forms/AuthenticationForm.tsx b/src/frontend/src/components/forms/AuthenticationForm.tsx
index b0ff229480..b0f6b5f0e5 100644
--- a/src/frontend/src/components/forms/AuthenticationForm.tsx
+++ b/src/frontend/src/components/forms/AuthenticationForm.tsx
@@ -4,7 +4,6 @@ import {
   Button,
   Group,
   Loader,
-  Paper,
   PasswordInput,
   Stack,
   Text,
@@ -17,7 +16,10 @@ import { IconCheck } from '@tabler/icons-react';
 import { useState } from 'react';
 import { useNavigate } from 'react-router-dom';
 
+import { api } from '../../App';
+import { ApiPaths } from '../../enums/ApiEndpoints';
 import { doClassicLogin, doSimpleLogin } from '../../functions/auth';
+import { apiUrl } from '../../states/ApiState';
 
 export function AuthenticationForm() {
   const classicForm = useForm({
@@ -79,50 +81,178 @@ export function AuthenticationForm() {
   }
 
   return (
-    
-      
-        Welcome, log in below
-      
-      
+  );
+}
+
+export function RegistrationForm() {
+  const registrationForm = useForm({
+    initialValues: { username: '', email: '', password1: '', password2: '' }
+  });
+  const navigate = useNavigate();
+  const [isRegistering, setIsRegistering] = useState(false);
+
+  function handleRegistration() {
+    setIsRegistering(true);
+    api
+      .post(apiUrl(ApiPaths.user_register), registrationForm.values, {
+        headers: { Authorization: '' }
+      })
+      .then((ret) => {
+        if (ret?.status === 204) {
+          setIsRegistering(false);
+          notifications.show({
+            title: t`Registration successful`,
+            message: t`Please confirm your email address to complete the registration`,
+            color: 'green',
+            icon: 
+          });
+          navigate('/home');
+        }
+      })
+      .catch((err) => {
+        if (err.response.status === 400) {
+          setIsRegistering(false);
+          for (const [key, value] of Object.entries(err.response.data)) {
+            registrationForm.setFieldError(key, value as string);
+          }
+          let err_msg = '';
+          if (err.response?.data?.non_field_errors) {
+            err_msg = err.response.data.non_field_errors;
+          }
+          notifications.show({
+            title: t`Input error`,
+            message: t`Check your input and try again. ` + err_msg,
+            color: 'red',
+            autoClose: 30000
+          });
+        }
+      });
+  }
+
+  return (
+    
+  );
+}
+
+export function ModeSelector({
+  loginMode,
+  setMode
+}: {
+  loginMode: boolean;
+  setMode: any;
+}) {
+  return (
+    
+      {loginMode ? (
+        <>
+          Don't have an account?{' '}
            setMode.toggle()}
           >
-            {classicLoginMode ? (
-              Send me an email
-            ) : (
-              I will use username and password
-            )}
+            Register
           
-          
-        
-      
-    
+        >
+      ) : (
+         setMode.toggle()}
+        >
+          Go back to login
+        
+      )}
+    
   );
 }
diff --git a/src/frontend/src/enums/ApiEndpoints.tsx b/src/frontend/src/enums/ApiEndpoints.tsx
index d5f676c73a..24388bec07 100644
--- a/src/frontend/src/enums/ApiEndpoints.tsx
+++ b/src/frontend/src/enums/ApiEndpoints.tsx
@@ -20,6 +20,7 @@ export enum ApiPaths {
   user_email_primary = 'api-user-email-primary',
   user_email_remove = 'api-user-email-remove',
   user_logout = 'api-user-logout',
+  user_register = 'api-user-register',
 
   user_list = 'api-user-list',
   group_list = 'api-group-list',
diff --git a/src/frontend/src/pages/Auth/Login.tsx b/src/frontend/src/pages/Auth/Login.tsx
index 00abb1f5b0..16de1b7509 100644
--- a/src/frontend/src/pages/Auth/Login.tsx
+++ b/src/frontend/src/pages/Auth/Login.tsx
@@ -1,12 +1,16 @@
-import { t } from '@lingui/macro';
-import { Center, Container } from '@mantine/core';
-import { useToggle } from '@mantine/hooks';
+import { Trans, t } from '@lingui/macro';
+import { Center, Container, Paper, Text } from '@mantine/core';
+import { useDisclosure, useToggle } from '@mantine/hooks';
 import { useEffect } from 'react';
 import { useNavigate } from 'react-router-dom';
 
 import { setApiDefaults } from '../../App';
 import { AuthFormOptions } from '../../components/forms/AuthFormOptions';
-import { AuthenticationForm } from '../../components/forms/AuthenticationForm';
+import {
+  AuthenticationForm,
+  ModeSelector,
+  RegistrationForm
+} from '../../components/forms/AuthenticationForm';
 import { InstanceOptions } from '../../components/forms/InstanceOptions';
 import { defaultHostKey } from '../../defaults/defaultHostList';
 import { checkLoginState } from '../../functions/auth';
@@ -26,6 +30,7 @@ export default function Login() {
   const hostname =
     hostList[hostKey] === undefined ? t`No selection` : hostList[hostKey]?.name;
   const [hostEdit, setHostEdit] = useToggle([false, true] as const);
+  const [loginMode, setMode] = useDisclosure(true);
   const navigate = useNavigate();
 
   // Data manipulation functions
@@ -63,7 +68,13 @@ export default function Login() {
           />
         ) : (
           <>
-            
+            
+              
+                Welcome, log in below
+              
+              {loginMode ?  : }
+              
+            
             
           >
         )}
diff --git a/src/frontend/src/states/ApiState.tsx b/src/frontend/src/states/ApiState.tsx
index 473e84bb6d..e4a17fd4c1 100644
--- a/src/frontend/src/states/ApiState.tsx
+++ b/src/frontend/src/states/ApiState.tsx
@@ -97,6 +97,8 @@ export function apiEndpoint(path: ApiPaths): string {
       return 'auth/emails/:id/primary/';
     case ApiPaths.user_logout:
       return 'auth/logout/';
+    case ApiPaths.user_register:
+      return 'auth/registration/';
     case ApiPaths.currency_list:
       return 'currency/exchange/';
     case ApiPaths.currency_refresh: