diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index bd48e4e07fb4297b189958be2766dcfbf2d3a621..3724ab19a92e6014acb3ec7011148ea558b2587b 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -32,6 +32,7 @@
         "i18next": "^20.6.0",
         "i18next-browser-languagedetector": "^6.1.2",
         "i18next-http-backend": "^1.3.1",
+        "libphonenumber-js": "^1.9.35",
         "react": "^17.0.2",
         "react-datepicker": "^4.2.1",
         "react-dom": "^17.0.2",
@@ -13856,6 +13857,11 @@
         "node": ">= 0.8.0"
       }
     },
+    "node_modules/libphonenumber-js": {
+      "version": "1.9.35",
+      "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.9.35.tgz",
+      "integrity": "sha512-6ok1JD4GcU7owpbp07WJZlxoGdlY538OCgN9fmOlWwCzqPNLzra7tvaFz7NJP8Hcmp1lkm97wNZ2hICN9uGylg=="
+    },
     "node_modules/lines-and-columns": {
       "version": "1.1.6",
       "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
@@ -33040,6 +33046,11 @@
         "type-check": "~0.4.0"
       }
     },
+    "libphonenumber-js": {
+      "version": "1.9.35",
+      "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.9.35.tgz",
+      "integrity": "sha512-6ok1JD4GcU7owpbp07WJZlxoGdlY538OCgN9fmOlWwCzqPNLzra7tvaFz7NJP8Hcmp1lkm97wNZ2hICN9uGylg=="
+    },
     "lines-and-columns": {
       "version": "1.1.6",
       "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index d58a3affc08aa3e8608bd22b8be4b9abd869bde8..8048554994014c225236c156172982cb61f3a8b6 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -27,6 +27,7 @@
     "i18next": "^20.6.0",
     "i18next-browser-languagedetector": "^6.1.2",
     "i18next-http-backend": "^1.3.1",
+    "libphonenumber-js": "^1.9.35",
     "react": "^17.0.2",
     "react-datepicker": "^4.2.1",
     "react-dom": "^17.0.2",
diff --git a/frontend/public/locales/en/common.json b/frontend/public/locales/en/common.json
index c5e5e7350a3ef79c9fed8a541408f78e033c5799..8c7ae1d54760d266622b59170adc54721c5fbfa1 100644
--- a/frontend/public/locales/en/common.json
+++ b/frontend/public/locales/en/common.json
@@ -50,7 +50,8 @@
     "nationalIdNumberRequired": "National ID number required",
     "roleTypeRequired": "Role type is required",
     "roleEndRequired": "Role end date is required",
-    "emailRequired": "E-mail is required"
+    "emailRequired": "E-mail is required",
+    "invalidMobilePhoneNumber": "Invalid phone number"
   },
   "button": {
     "back": "Back",
diff --git a/frontend/public/locales/nb/common.json b/frontend/public/locales/nb/common.json
index 67239ab90429c20ff6083251b7058dfd8eba4776..9e57b96bbdc37475ed51e98a1362852bb663d503 100644
--- a/frontend/public/locales/nb/common.json
+++ b/frontend/public/locales/nb/common.json
@@ -50,7 +50,8 @@
     "nationalIdNumberRequired": "Fødselsnummer er påkrevd",
     "roleTypeRequired": "Rolletype er påkrevd",
     "roleEndRequired": "Sluttdato for rolle er påkrevd",
-    "emailRequired": "E-post er obligatorisk"
+    "emailRequired": "E-post er obligatorisk",
+    "invalidMobilePhoneNumber": "Ugyldig telefonnummer"
   },
   "button": {
     "back": "Tilbake",
diff --git a/frontend/public/locales/nn/common.json b/frontend/public/locales/nn/common.json
index 0c80b604abffb7bb7a7861173ebeb058600f16b4..17c7a2426d86f8bf499f2abfac18e768a91832d0 100644
--- a/frontend/public/locales/nn/common.json
+++ b/frontend/public/locales/nn/common.json
@@ -52,6 +52,7 @@
     "roleTypeRequired": "Rolletype er påkrevd",
     "roleEndRequired": "Sluttdato for rolle er påkrevd",
     "emailRequired": "E-post er obligatorisk"
+    "invalidMobilePhoneNumber": "Ugyldig telefonnummer"
   },
   "button": {
     "back": "Tilbake",
diff --git a/frontend/src/utils/index.test.ts b/frontend/src/utils/index.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..766fcd120c90747de174fd7f61f9779ced7a5e5c
--- /dev/null
+++ b/frontend/src/utils/index.test.ts
@@ -0,0 +1,14 @@
+import { isValidMobilePhoneNumber } from './index'
+
+// Mock i18next module to return a translation that just returns the key
+jest.mock('i18next', () => ({
+  t: (value: string) => value,
+}))
+
+test('Invalid phone number', async () => {
+  expect(isValidMobilePhoneNumber('dafasfdsfasdf')).not.toEqual(true)
+})
+
+test('Valid phone number', async () => {
+  expect(isValidMobilePhoneNumber('+47 97510000')).toEqual(true)
+})
diff --git a/frontend/src/utils/index.ts b/frontend/src/utils/index.ts
index f269b160aac3b663ad716744d901823f859a7d38..d7a9f1b8fd0983c828dc5d335c631611f6a501cd 100644
--- a/frontend/src/utils/index.ts
+++ b/frontend/src/utils/index.ts
@@ -1,52 +1,64 @@
 import validator from '@navikt/fnrvalidator'
 import i18n from 'i18next'
+import {isValidPhoneNumber} from 'libphonenumber-js'
 
 export function getCookie(name: string) {
-  if (!document.cookie) {
-    return null
-  }
+    if (!document.cookie) {
+        return null
+    }
 
-  const cookies = document.cookie
-    .split(';')
-    .map((c) => c.trim())
-    .filter((c) => c.startsWith(`${name}=`))
+    const cookies = document.cookie
+        .split(';')
+        .map((c) => c.trim())
+        .filter((c) => c.startsWith(`${name}=`))
 
-  if (cookies.length === 0) {
-    return null
-  }
-  return decodeURIComponent(cookies[0].split('=')[1])
+    if (cookies.length === 0) {
+        return null
+    }
+    return decodeURIComponent(cookies[0].split('=')[1])
 }
 
 export function maybeCsrfToken() {
-  const csrfToken = getCookie('csrftoken')
-  if (!csrfToken) {
-    return null
-  }
-  return {
-    'X-CSRFToken': csrfToken,
-  }
+    const csrfToken = getCookie('csrftoken')
+    if (!csrfToken) {
+        return null
+    }
+    return {
+        'X-CSRFToken': csrfToken,
+    }
 }
 
 export function postJsonOpts(data: object): RequestInit {
-  return {
-    method: 'POST',
-    headers: {
-      'Content-Type': 'application/json',
-      ...maybeCsrfToken(),
-    },
-    body: JSON.stringify(data),
-    credentials: 'same-origin',
-  }
+    return {
+        method: 'POST',
+        headers: {
+            'Content-Type': 'application/json',
+            ...maybeCsrfToken(),
+        },
+        body: JSON.stringify(data),
+        credentials: 'same-origin',
+    }
 }
 
 export function isValidFnr(data: string | undefined): boolean | string {
-  if (data === null) {
+    if (data === null) {
+        return i18n.t('common:validation.invalidIdNumber').toString()
+    }
+    const valid = validator.idnr(data as string).status === 'valid'
+    if (valid) {
+        return true
+    }
+    // TypeScript complains if toString is not used on the function result
     return i18n.t('common:validation.invalidIdNumber').toString()
-  }
-  const valid = validator.idnr(data as string).status === 'valid'
-  if (valid) {
-    return true
-  }
-  // TypeScript complains if toString is not used on the function result
-  return i18n.t('common:validation.invalidIdNumber').toString()
 }
+
+export function isValidMobilePhoneNumber(data: string | undefined): boolean | string {
+    if (!data) {
+        return i18n.t<string>('common:validation.invalidMobilePhoneNumber')
+    }
+    const valid = isValidPhoneNumber(data)
+    if (valid) {
+        return true
+    }
+    return i18n.t<string>('common:validation.invalidMobilePhoneNumber')
+}
\ No newline at end of file