diff --git a/frontend/src/utils/PathSplitter.test.js b/frontend/src/utils/PathSplitter.test.js
new file mode 100644
index 0000000..4a545c4
--- /dev/null
+++ b/frontend/src/utils/PathSplitter.test.js
@@ -0,0 +1,78 @@
+import {splitPath} from "./PathSplitter"
+
+
+test("splits empty path", () => {
+    expect(
+        splitPath("/")
+    ).toMatchObject(
+        {}
+    )
+})
+
+test("splits instance path", () => {
+    expect(
+        splitPath("/i/https:api:sophon:steffo:eu:")
+    ).toMatchObject(
+        {
+            instance: "https:api:sophon:steffo:eu:"
+        }
+    )
+})
+
+test("splits username path", () => {
+    expect(
+        splitPath("/i/https:api:sophon:steffo:eu:/u/steffo")
+    ).toMatchObject(
+        {
+            instance: "https:api:sophon:steffo:eu:",
+            userName: "steffo",
+        }
+    )
+})
+
+test("splits userid path", () => {
+    expect(
+        splitPath("/i/https:api:sophon:steffo:eu:/u/1")
+    ).toMatchObject(
+        {
+            instance: "https:api:sophon:steffo:eu:",
+            userId: "1",
+        }
+    )
+})
+
+test("splits research group path", () => {
+    expect(
+        splitPath("/i/https:api:sophon:steffo:eu:/g/testers")
+    ).toMatchObject(
+        {
+            instance: "https:api:sophon:steffo:eu:",
+            researchGroup: "testers",
+        }
+    )
+})
+
+test("splits research project path", () => {
+    expect(
+        splitPath("/i/https:api:sophon:steffo:eu:/g/testers/p/test")
+    ).toMatchObject(
+        {
+            instance: "https:api:sophon:steffo:eu:",
+            researchGroup: "testers",
+            researchProject: "test",
+        }
+    )
+})
+
+test("splits research project path", () => {
+    expect(
+        splitPath("/i/https:api:sophon:steffo:eu:/g/testers/p/test/n/testerino")
+    ).toMatchObject(
+        {
+            instance: "https:api:sophon:steffo:eu:",
+            researchGroup: "testers",
+            researchProject: "test",
+            notebook: "testerino",
+        }
+    )
+})
diff --git a/frontend/src/utils/PathSplitter.ts b/frontend/src/utils/PathSplitter.ts
new file mode 100644
index 0000000..66ad8d1
--- /dev/null
+++ b/frontend/src/utils/PathSplitter.ts
@@ -0,0 +1,52 @@
+/**
+ * Possible contents of the path.
+ */
+export interface SplitPath {
+    /**
+     * The URL of the Sophon instance.
+     */
+    instance?: string,
+
+    /**
+     * The numeric id of the user.
+     */
+    userId?: string,
+
+    /**
+     * The username of the user.
+     * @warning Matches {@link userId} if it is defined.
+     */
+    userName?: string,
+
+    /**
+     * The research group slug.
+     */
+    researchGroup?: string,
+
+    /**
+     * The research project slug.
+     */
+    researchProject?: string,
+
+    /**
+     * The notebook slug.
+     */
+    notebook?: string,
+}
+
+/**
+ * Split the URL path into various components.
+ * @param path - The path to split.
+ */
+export function splitPath(path: string): SplitPath {
+    let result: SplitPath = {}
+
+    result.instance =        path.match(/[/]i[/]([^/]+)/)         ?.[1]
+    result.userId =          path.match(/[/]u[/]([0-9]+)/)        ?.[1]
+    result.userName =        path.match(/[/]u[/]([A-Za-z0-9_-]+)/)?.[1]
+    result.researchGroup =   path.match(/[/]g[/]([A-Za-z0-9_-]+)/)?.[1]
+    result.researchProject = path.match(/[/]p[/]([A-Za-z0-9_-]+)/)?.[1]
+    result.notebook =        path.match(/[/]n[/]([A-Za-z0-9_-]+)/)?.[1]
+
+    return result
+}