diff --git a/packages/chronicle/src/server/App.module.css b/packages/chronicle/src/server/App.module.css
new file mode 100644
index 0000000..0864892
--- /dev/null
+++ b/packages/chronicle/src/server/App.module.css
@@ -0,0 +1,4 @@
+.fallback {
+ padding: var(--rs-space-8);
+ width: 80%;
+}
diff --git a/packages/chronicle/src/server/App.tsx b/packages/chronicle/src/server/App.tsx
index 16db22e..cfa7fc2 100644
--- a/packages/chronicle/src/server/App.tsx
+++ b/packages/chronicle/src/server/App.tsx
@@ -1,17 +1,20 @@
import '@raystack/apsara/normalize.css';
import '@raystack/apsara/style.css';
-import { ThemeProvider } from '@raystack/apsara';
+import { ThemeProvider, Skeleton, Flex } from '@raystack/apsara';
+import { lazy, Suspense } from 'react';
import { Navigate, useLocation } from 'react-router';
import { Head } from '@/lib/head';
import { usePageContext } from '@/lib/page-context';
import { resolveRoute, RouteType } from '@/lib/route-resolver';
-import { ApiLayout } from '@/pages/ApiLayout';
-import { ApiPage } from '@/pages/ApiPage';
-import { DocsLayout } from '@/pages/DocsLayout';
-import { DocsPage } from '@/pages/DocsPage';
-import { LandingPage } from '@/pages/LandingPage';
import type { ChronicleConfig } from '@/types';
import { getThemeConfig } from '@/themes/registry';
+import styles from './App.module.css';
+
+const ApiLayout = lazy(() => import('@/pages/ApiLayout').then(m => ({ default: m.ApiLayout })));
+const ApiPage = lazy(() => import('@/pages/ApiPage').then(m => ({ default: m.ApiPage })));
+const DocsLayout = lazy(() => import('@/pages/DocsLayout').then(m => ({ default: m.DocsLayout })));
+const DocsPage = lazy(() => import('@/pages/DocsPage').then(m => ({ default: m.DocsPage })));
+const LandingPage = lazy(() => import('@/pages/LandingPage').then(m => ({ default: m.LandingPage })));
export function App() {
const { pathname } = useLocation();
@@ -35,19 +38,33 @@ export function App() {
forcedTheme={themeConfig.forcedTheme}
>