diff --git a/package.json b/package.json
index 8f744b9..ee49e4b 100644
--- a/package.json
+++ b/package.json
@@ -29,6 +29,7 @@
"jsmediatags": "^3.9.7",
"react": "18.2.0",
"react-dom": "18.2.0",
+ "react-helmet": "^6.1.0",
"react-hook-form": "^7.51.0",
"react-native": "0.73.4",
"react-native-circular-progress": "^1.3.9",
@@ -52,6 +53,7 @@
},
"devDependencies": {
"@babel/core": "^7.20.0",
+ "@types/react-helmet": "^6.1.11",
"babel-plugin-module-resolver": "^5.0.0",
"patch-package": "^8.0.0",
"react-native-svg-transformer": "^1.3.0"
diff --git a/src/app/apps/files.tsx b/src/app/apps/files.tsx
index 5fe45c3..bab2196 100644
--- a/src/app/apps/files.tsx
+++ b/src/app/apps/files.tsx
@@ -15,6 +15,7 @@ import { Ionicons } from "@ui/Icons";
import FileInlineViewer from "@/components/pages/files/FileInlineViewer";
import { FilesContext } from "@/components/pages/files/FilesContext";
import { FileItem } from "@/types/files";
+import Head from "@/components/utility/Head";
const FilesPage = () => {
const { isLoggedIn } = useAuth();
@@ -65,6 +66,7 @@ const FilesPage = () => {
return (
+
, title: "Files" }}
/>
diff --git a/src/app/apps/terminal.tsx b/src/app/apps/terminal.tsx
index 43ff78a..ebf81c7 100644
--- a/src/app/apps/terminal.tsx
+++ b/src/app/apps/terminal.tsx
@@ -11,6 +11,7 @@ import { BASEURL, WS_BASEURL } from "@/lib/constants";
import { useAuth } from "@/stores/authStore";
import { Stack } from "expo-router";
import BackButton from "@ui/BackButton";
+import Head from "@/components/utility/Head";
const isWeb = Platform.OS === "web";
@@ -82,6 +83,7 @@ const TerminalPage = () => {
return (
<>
+
}}
/>
diff --git a/src/app/apps/vnc.tsx b/src/app/apps/vnc.tsx
index 9273378..765e49d 100644
--- a/src/app/apps/vnc.tsx
+++ b/src/app/apps/vnc.tsx
@@ -10,6 +10,7 @@ import React, { useEffect, useRef } from "react";
import { Platform } from "react-native";
import { VncScreen, VncScreenHandle } from "react-vnc";
import { openFullscreen } from "./lib";
+import Head from "@/components/utility/Head";
const VncPage = () => {
const containerRef = useRef(null!);
@@ -26,6 +27,7 @@ const VncPage = () => {
return (
<>
+
{
const { isLoggedIn } = useAuth();
@@ -30,6 +31,7 @@ const HomePage = () => {
return (
+
diff --git a/src/components/utility/Head.tsx b/src/components/utility/Head.tsx
new file mode 100644
index 0000000..9ce2455
--- /dev/null
+++ b/src/components/utility/Head.tsx
@@ -0,0 +1,22 @@
+import React from "react";
+import { Platform } from "react-native";
+import Helmet from "react-helmet";
+import { APP_NAME } from "@/lib/constants";
+
+type HeadProps = {
+ title?: string;
+};
+
+const Head = ({ title }: HeadProps) => {
+ if (Platform.OS !== "web") {
+ return null;
+ }
+
+ return (
+
+ {title ? `${title} - ${APP_NAME}` : APP_NAME}
+
+ );
+};
+
+export default Head;
diff --git a/src/lib/constants.ts b/src/lib/constants.ts
index cba39d0..237a5e2 100644
--- a/src/lib/constants.ts
+++ b/src/lib/constants.ts
@@ -7,3 +7,5 @@ export const WS_BASEURL = BASEURL.replace("https://", "wss://").replace(
"http://",
"ws://"
);
+
+export const APP_NAME = "Home Lab";
diff --git a/yarn.lock b/yarn.lock
index 8f6a5b6..5dfed08 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2395,6 +2395,22 @@
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563"
integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==
+"@types/react-helmet@^6.1.11":
+ version "6.1.11"
+ resolved "https://registry.yarnpkg.com/@types/react-helmet/-/react-helmet-6.1.11.tgz#8cafcafff38f75361f451563ba7b406b0c5d3907"
+ integrity sha512-0QcdGLddTERotCXo3VFlUSWO3ztraw8nZ6e3zJSgG7apwV5xt+pJUS8ewPBqT4NYB1optGLprNQzFleIY84u/g==
+ dependencies:
+ "@types/react" "*"
+
+"@types/react@*":
+ version "18.2.67"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.67.tgz#96b7af0b5e79c756f4bdd981de2ca28472c858e5"
+ integrity sha512-vkIE2vTIMHQ/xL0rgmuoECBCkZFZeHr49HeWSc24AptMbNRo7pwSBvj73rlJJs9fGKj0koS+V7kQB1jHS0uCgw==
+ dependencies:
+ "@types/prop-types" "*"
+ "@types/scheduler" "*"
+ csstype "^3.0.2"
+
"@types/react@~18.2.45":
version "18.2.66"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.66.tgz#d2eafc8c4e70939c5432221adb23d32d76bfe451"
@@ -6354,7 +6370,7 @@ react-dom@18.2.0:
loose-envify "^1.1.0"
scheduler "^0.23.0"
-react-fast-compare@^3.2.0:
+react-fast-compare@^3.1.1, react-fast-compare@^3.2.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49"
integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==
@@ -6375,6 +6391,16 @@ react-helmet-async@^1.3.0:
react-fast-compare "^3.2.0"
shallowequal "^1.1.0"
+react-helmet@^6.1.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/react-helmet/-/react-helmet-6.1.0.tgz#a750d5165cb13cf213e44747502652e794468726"
+ integrity sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==
+ dependencies:
+ object-assign "^4.1.1"
+ prop-types "^15.7.2"
+ react-fast-compare "^3.1.1"
+ react-side-effect "^2.1.0"
+
react-hook-form@^7.51.0:
version "7.51.0"
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.51.0.tgz#757ae71b37c26e00590bd3788508287dcc5ecdaf"
@@ -6541,6 +6567,11 @@ react-shallow-renderer@^16.15.0:
object-assign "^4.1.1"
react-is "^16.12.0 || ^17.0.0 || ^18.0.0"
+react-side-effect@^2.1.0:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-2.1.2.tgz#dc6345b9e8f9906dc2eeb68700b615e0b4fe752a"
+ integrity sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw==
+
react-vnc@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/react-vnc/-/react-vnc-1.0.0.tgz#6ddaa877265a034fe33934f2ca09ceecbfda1789"