diff --git a/apps/docs/.vitepress/theme/Layout.vue b/apps/docs/.vitepress/theme/Layout.vue
index 9976dce3..ba76b08b 100644
--- a/apps/docs/.vitepress/theme/Layout.vue
+++ b/apps/docs/.vitepress/theme/Layout.vue
@@ -16,5 +16,59 @@ const { Layout } = DefaultTheme;
+
+
+
🦦
+
Hello from the otter side!
+
This page swam away. Let's get you back on track.
+
Back to docs
+
+
+
+
diff --git a/apps/landing/src/app/not-found.tsx b/apps/landing/src/app/not-found.tsx
new file mode 100644
index 00000000..89c5fd94
--- /dev/null
+++ b/apps/landing/src/app/not-found.tsx
@@ -0,0 +1,26 @@
+import { Footer } from "@/components/footer";
+import { Navbar } from "@/components/navbar";
+
+export default function NotFound() {
+ return (
+ <>
+
+
+ 🦦
+
+ Hello from the otter side!
+
+
+ This page swam away. Let's get you back on track.
+
+
+ Back to homepage
+
+
+
+ >
+ );
+}
diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx
index a9ca89a1..325a106b 100644
--- a/apps/web/src/App.tsx
+++ b/apps/web/src/App.tsx
@@ -1,7 +1,7 @@
import { APP_VERSION, en, shouldShowConsent } from "@snapotter/shared";
import { Component, type ErrorInfo, lazy, type ReactNode, Suspense, useEffect } from "react";
import { BrowserRouter, Navigate, Route, Routes, useLocation } from "react-router-dom";
-import { Toaster } from "sonner";
+import { Toaster, toast } from "sonner";
import { ConnectionMonitor } from "./components/common/connection-monitor";
import { KeyboardShortcutProvider } from "./components/common/keyboard-shortcut-provider";
import { I18nProvider } from "./contexts/i18n-context";
@@ -186,6 +186,15 @@ export function App() {
fetchAnalyticsConfig();
}, [fetchAnalyticsConfig]);
+ useEffect(() => {
+ if (localStorage.getItem("snapotter-welcome") === "1") {
+ localStorage.removeItem("snapotter-welcome");
+ toast("Hello from the otter side! 🦦", {
+ duration: 5000,
+ });
+ }
+ }, []);
+
useEffect(() => {
if (
!analyticsConfigLoaded ||
diff --git a/apps/web/src/pages/change-password-page.tsx b/apps/web/src/pages/change-password-page.tsx
index 3a11b314..e00ae94b 100644
--- a/apps/web/src/pages/change-password-page.tsx
+++ b/apps/web/src/pages/change-password-page.tsx
@@ -100,6 +100,7 @@ export function ChangePasswordPage() {
return;
}
+ localStorage.setItem("snapotter-welcome", "1");
// Trigger browser password save prompt via real form submission + navigation
const username = localStorage.getItem("snapotter-username") || "admin";
triggerBrowserPasswordSave(username, newPassword);
@@ -218,6 +219,7 @@ export function ChangePasswordPage() {
+
🦦
{t.changePassword.sidebarTitle}
{t.changePassword.sidebarDescription}
diff --git a/packages/shared/src/i18n/en.ts b/packages/shared/src/i18n/en.ts
index c1ab02ce..c2eb412b 100644
--- a/packages/shared/src/i18n/en.ts
+++ b/packages/shared/src/i18n/en.ts
@@ -1687,8 +1687,8 @@ export const en = {
connectionError: "Connection error",
changingButton: "Changing...",
changeButton: "Change password",
- sidebarTitle: "Almost there",
- sidebarDescription: "Set a strong password to secure your account, then you are good to go.",
+ sidebarTitle: "Hello from the otter side!",
+ sidebarDescription: "Set a strong password to secure your account, then you're good to go.",
},
automate: {
title: "Automate",