diff --git a/.gitignore b/.gitignore
index 403adbc1e527906a4aa59558cd582c20bcd1d738..0035d70c2cfab2a247a93613b879c88a6b2fba6b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@ node_modules
 
 
 # local env files
+.env
 .env.local
 .env.*.local
 
diff --git a/src/components/LoginForm.vue b/src/components/LoginForm.vue
index 101a2df55ba33682c0ad1224bdd67d6d54960f4a..82ba58cdfb84ebc5cf9fa14c76374d5661705cec 100644
--- a/src/components/LoginForm.vue
+++ b/src/components/LoginForm.vue
@@ -1,70 +1,127 @@
-<!--suppress HtmlDeprecatedAttribute -->
 <template>
-  <div>
-    <v-col align="center" justify="space-around" class="mt-16">
-      <v-img
-        max-width="45%"
-        :src="require('../assets/logo3.svg')"
-        align="center"
-      ></v-img>
-    </v-col>
-
-    <v-form ref="form" v-model="valid" lazy-validation>
-      <v-col>
-        <v-text-field
-          v-model="user.email"
-          :rules="[rules.email]"
-          label="Epost"
+  <div class="App">
+    <div id="logoField" class="flex justify-center m-6">
+      <img src="../assets/logo3.svg" alt="BoCo logo" />
+    </div>
+
+    <div
+      id="emailField"
+      class="m-6"
+      :class="{ error: v$.user.email.$errors.length }"
+    >
+      <div class="mb-6">
+        <label
+          for="email"
+          class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300"
+          >E-post</label
+        >
+        <input
+          type="email"
+          id="email"
+          class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
+          placeholder="eksempel@eksempel.no"
+          v-model="v$.user.email.$model"
           required
-        ></v-text-field>
-      </v-col>
-
-      <v-col align="right">
-        <v-text-field
-          v-model="user.password"
-          :append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
-          :rules="[rules.required, rules.min]"
-          :type="showPassword ? 'text' : 'password'"
-          name="input-10-1"
-          label="Passord"
-          counter
-          @click:append="showPassword = !showPassword"
-        ></v-text-field>
-
-        <div class="text-decoration-underline mt-n4 mr-10">Glemt passord</div>
-      </v-col>
-
-      <v-col align="center" justify="space-around">
-        <v-btn
-          :disabled="!valid"
-          color="success"
-          class="mb-4 mt-4"
-          width="50%"
-          height="40px"
-          @click="loginClicked"
+        />
+        <!-- error message -->
+        <div v-for="(error, index) of v$.user.email.$errors" :key="index">
+          <div
+            class="text-red-600 text-sm"
+            v-show="showError"
+            id="emailErrorId"
+          >
+            {{ error.$message }}
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <div
+      id="passwordField"
+      class="m-6"
+      :class="{ error: v$.user.password.$errors.length }"
+    >
+      <label
+        for="password"
+        class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300"
+        >Passord</label
+      >
+      <input
+        type="password"
+        id="password"
+        class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
+        v-model="v$.user.password.$model"
+        required
+      />
+      <!-- error message -->
+      <div
+        class="text-red"
+        v-for="(error, index) of v$.user.password.$errors"
+        :key="index"
+      >
+        <div
+          class="text-red-600 text-sm"
+          v-show="showError"
+          id="passwordErrorId"
         >
-          Logg inn
-        </v-btn>
+          {{ error.$message }}
+        </div>
+      </div>
+    </div>
 
-        <div>
-          <a href="/" class="text-decoration-none">Ny bruker</a>
+    <div id="buttonsField" class="m-6">
+      <div class="align-items: flex-end; mb-6">
+        <div class="ml-3 text-sm">
+          <router-link to="about" class="text-blue-600"
+            >Glemt passord</router-link
+          >
+        </div>
+      </div>
+      <button
+        @click="loginClicked"
+        class="flex justify-center align-items: flex-end; text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
+      >
+        Logg inn
+      </button>
+      <div class="flex justify-center align-items: flex-end; mb-6 mt-6">
+        <div class="ml-3 text-sm">
+          <router-link to="register" class="text-blue-600"
+            >Ny bruker</router-link
+          >
         </div>
-      </v-col>
-    </v-form>
-    <label>{{ message }}</label>
+      </div>
+      <div class="flex flex-row min-h-screen justify-center items-center">
+        <label>{{ message }}</label>
+      </div>
+    </div>
   </div>
 </template>
 
 <script>
+import useVuelidate from "@vuelidate/core";
+import { required, email, helpers } from "@vuelidate/validators";
 import { doLogin } from "@/utils/apiutil";
-import { mapState } from "vuex";
 
 export default {
   name: "LoginForm.vue",
 
-  computed: mapState({
-    token: (state) => state.user.token,
-  }),
+  setup() {
+    return { v$: useVuelidate() };
+  },
+
+  validations() {
+    return {
+      user: {
+        email: {
+          required,
+          email: helpers.withMessage(`E-posten er ugyldig`, email),
+        },
+        password: {
+          required,
+        },
+      },
+    };
+  },
 
   data() {
     return {
@@ -74,33 +131,34 @@ export default {
         password: "",
       },
 
-      showPassword: false,
-      valid: true,
-      rules: {
-        required: (value) => !!value || "Feltet er påkrevd",
-        min: (v) => v.length >= 8 || "Minimum 8 tegn",
-        email: (v) => /.+@.+\..+/.test(v) || "Epost adressen må være gyldig",
-      },
+      showError: false,
     };
   },
 
   methods: {
     async loginClicked() {
-      console.log(this.user.email + " " + this.user.password);
+      this.showError = true;
+
+      this.v$.user.email.$touch();
+
+      if (this.v$.user.email.$invalid) {
+        console.log("Ugyldig, avslutter...");
+        return;
+      }
+
       const loginRequest = {
         email: this.user.email,
         password: this.user.password,
       };
+
       const loginResponse = await doLogin(loginRequest);
 
-      if (loginResponse === "Failed login") {
-        this.message = "Feil brukernavn/passord";
+      if (loginResponse.data === "Login failed") {
+        this.message = "Feil e-post/passord";
         this.$store.commit("logout");
-        return;
+      } else {
+        this.$store.commit("saveToken", loginResponse);
       }
-
-      this.$store.commit("saveToken", loginResponse);
-      console.log(loginResponse);
     },
 
     validate() {
diff --git a/src/utils/apiutil.js b/src/utils/apiutil.js
index 773bd8d67e484a1f42d371339b5a46ce757a9347..8812b429588b3974d65292f39fcc60bd4dc3647c 100644
--- a/src/utils/apiutil.js
+++ b/src/utils/apiutil.js
@@ -2,8 +2,12 @@ import axios from "axios";
 
 export function doLogin(loginRequest) {
   return axios
-    .post(`http://65.108.62.223:3000/api/login/authentication`, loginRequest)
+    .post(process.env.VUE_APP_BASEURL + "login/authentication", loginRequest)
     .then((response) => {
       return response.data;
+    })
+    .catch((error) => {
+      console.log(error.response);
+      return error.response;
     });
 }