diff --git a/src/components/Loader.tsx b/src/components/Loader.tsx
new file mode 100644
index 0000000..e1c58c3
--- /dev/null
+++ b/src/components/Loader.tsx
@@ -0,0 +1,34 @@
+import type { ReactNode } from "react";
+
+/**
+ * Loader component for displaying a loading spinner or message during async route loads.
+ * Accepts optional children to customize the loading message.
+ */
+export function Loader({ children }: { children?: ReactNode }) {
+ return (
+
+
+ {children ||
Loading…}
+
+ );
+}
diff --git a/src/routes/_authenticated/campaigns.index.tsx b/src/routes/_authenticated/campaigns.index.tsx
index 2f77685..713d848 100644
--- a/src/routes/_authenticated/campaigns.index.tsx
+++ b/src/routes/_authenticated/campaigns.index.tsx
@@ -2,6 +2,7 @@ import { createFileRoute } from "@tanstack/react-router";
import { pb } from "@/lib/pocketbase";
import type { Campaign } from "@/lib/types";
import { Link } from "@tanstack/react-router";
+import { Loader } from "@/components/Loader";
export const Route = createFileRoute("/_authenticated/campaigns/")({
loader: async () => {
@@ -9,6 +10,7 @@ export const Route = createFileRoute("/_authenticated/campaigns/")({
return { campaigns: records.map((rec: any) => ({ id: rec.id, name: rec.name })) as Campaign[] };
},
component: RouteComponent,
+ pendingComponent: Loader,
});
function RouteComponent() {