diff --git a/app/academy/layout.tsx b/app/academy/layout.tsx
index d31dd495164..d86f9be66ad 100644
--- a/app/academy/layout.tsx
+++ b/app/academy/layout.tsx
@@ -1,32 +1,20 @@
import { DocsLayout, type DocsLayoutProps } from 'fumadocs-ui/layouts/notebook';
+import { HomeLayout } from 'fumadocs-ui/layouts/home';
import type { ReactNode } from 'react';
-import { baseOptions, docsMenu, consoleMenu, integrationsMenu, userMenu } from '@/app/layout.config';
+import { baseOptions } from '@/app/layout.config';
import { academy } from '@/lib/source';
-import { AvalancheLogo } from '@/components/navigation/avalanche-logo';
+import './styles.css';
const academyOptions: DocsLayoutProps = {
- ...baseOptions,
+ tree: academy.pageTree,
nav: {
- mode: "top" as const,
- title: (
- <>
- {}
- Academy
- >
- ),
- url: '/academy',
+ enabled: false,
},
- tree: academy.pageTree,
- links: [
- consoleMenu,
- docsMenu,
- integrationsMenu,
- userMenu
- ],
};
export default function Layout({ children }: { children: ReactNode }) {
return (
+
{children}
+
);
}
\ No newline at end of file
diff --git a/app/academy/styles.css b/app/academy/styles.css
new file mode 100644
index 00000000000..bc66d8d5414
--- /dev/null
+++ b/app/academy/styles.css
@@ -0,0 +1,29 @@
+/* Increase spacing between the main navbar and the academy sidebar dropdown */
+@media (min-width: 768px) {
+ #nd-sidebar > div:first-child {
+ padding-top: calc(var(--spacing) * 7.5);
+ }
+}
+
+/* Remove thin separator line from library defaults under navbar */
+body > div > nav[aria-label="Main"],
+.nd-layout-home > nav:not([role="tablist"]):not(.nd-tabs-nav),
+.nd-layout-home > header:not([role="tablist"]):not(.nd-tabs-nav) {
+ border-bottom: 0 !important;
+ box-shadow: none !important;
+}
+
+/* Remove any top border drawn directly under the navbar */
+nav[aria-label="Main"] + *,
+header + * {
+ border-top: 0 !important;
+ box-shadow: none !important;
+}
+
+/* Fumadocs DocsNavbar adds border-b on internal containers; remove it */
+#nd-subnav .border-b {
+ border-bottom: 0 !important;
+ box-shadow: none !important;
+}
+
+
diff --git a/app/docs/layout.tsx b/app/docs/layout.tsx
index 5a1d2c34cd4..24252a342db 100644
--- a/app/docs/layout.tsx
+++ b/app/docs/layout.tsx
@@ -1,34 +1,22 @@
import { DocsLayout, type DocsLayoutProps } from 'fumadocs-ui/layouts/notebook';
+import { HomeLayout } from 'fumadocs-ui/layouts/home';
import type { ReactNode } from 'react';
-import { baseOptions, academyMenu, consoleMenu, integrationsMenu } from '@/app/layout.config';
+import { baseOptions } from '@/app/layout.config';
import { documentation } from '@/lib/source';
import 'fumadocs-twoslash/twoslash.css';
-import { AvalancheLogo } from '@/components/navigation/avalanche-logo';
+import './styles.css';
const docsOptions: DocsLayoutProps = {
-tree: documentation.pageTree,
-tabMode: 'navbar',
-nav: {
- ...baseOptions.nav,
- mode: 'top',
- title: (
- <>
- {}
- Documentation
- >
- ),
- url: '/docs',
+ tree: documentation.pageTree,
+ nav: {
+ enabled: false,
},
- links: [
- academyMenu,
- consoleMenu,
- integrationsMenu
- ]
};
export default function Layout({ children }: { children: ReactNode }) {
return (
-
+
+
{children}
-
+
+
);
}
\ No newline at end of file
diff --git a/app/docs/styles.css b/app/docs/styles.css
new file mode 100644
index 00000000000..c41a6dce7cd
--- /dev/null
+++ b/app/docs/styles.css
@@ -0,0 +1,59 @@
+/* Force ONLY main navbar to extend to left edge - DOCS PAGE ONLY */
+body {
+ padding-left: 0 !important;
+ margin-left: 0 !important;
+}
+
+/* Target only the main navbar, NOT the tabs nav */
+body > div > nav[aria-label="Main"],
+.nd-layout-home > nav:not([role="tablist"]):not(.nd-tabs-nav),
+.nd-layout-home > header:not([role="tablist"]):not(.nd-tabs-nav) {
+ padding-left: 0 !important;
+ margin-left: 0 !important;
+ width: 100vw !important;
+ max-width: 100vw !important;
+ /* Remove thin separator line from library defaults */
+ border-bottom: 0 !important;
+ box-shadow: none !important;
+}
+
+/* Container gets the padding instead - only for main nav */
+nav[aria-label="Main"] > div,
+.nd-layout-home > nav:not([role="tablist"]):not(.nd-tabs-nav) > div,
+.nd-layout-home > header:not([role="tablist"]):not(.nd-tabs-nav) > div {
+ padding-left: 1rem !important;
+ padding-right: 1rem !important;
+}
+
+/* Preserve normal styling for tabs nav */
+.nd-tabs-nav,
+nav[role="tablist"],
+[role="tablist"] {
+ width: auto !important;
+ max-width: none !important;
+ padding-left: 0 !important;
+}
+
+/* Add padding at top of docs content area */
+.nd-layout-notebook {
+ padding-top: 2rem !important;
+}
+
+/* Add padding to the main content container */
+main .nd-layout-notebook > div:first-child {
+ padding-top: 1rem !important;
+}
+
+/* Remove any top border drawn directly under the navbar */
+nav[aria-label="Main"] + *,
+header + * {
+ border-top: 0 !important;
+ box-shadow: none !important;
+}
+
+/* Fumadocs DocsNavbar adds border-b on internal containers; remove it */
+#nd-subnav .border-b {
+ border-bottom: 0 !important;
+ box-shadow: none !important;
+}
+
diff --git a/app/global.css b/app/global.css
index 3d9e2340383..b0d9d66fde1 100644
--- a/app/global.css
+++ b/app/global.css
@@ -10,7 +10,7 @@
@media (min-width: 768px) {
#nd-sidebar > div:first-child {
- padding-top: calc(var(--spacing) * 3.5);
+ padding-top: calc(var(--spacing) * 7.5);
}
}
/* @plugin "@tailwindcss/typography"; */
@@ -26,6 +26,49 @@ div.group\/accordion h3 {
margin-top: 0 !important;
}
+/* Remove ALL left whitespace from navbar to fill screen edge */
+body > div > nav,
+body > div > header,
+nav[aria-label="Main"],
+header nav,
+.nd-nav,
+.nd-layout-home > nav,
+.nd-layout-home > header {
+ padding-left: 0 !important;
+ margin-left: 0 !important;
+ padding-right: 0 !important;
+ margin-right: 0 !important;
+ max-width: 100% !important;
+}
+
+/* Remove container padding/margin */
+nav > div,
+header > div,
+nav[aria-label="Main"] > div,
+.nd-nav > div {
+ padding-left: 1rem !important;
+ padding-right: 1rem !important;
+ margin-left: 0 !important;
+ margin-right: 0 !important;
+ max-width: 100% !important;
+}
+
+/* Force the navbar to be full width */
+body > div:first-child,
+body > div > main {
+ padding-left: 0 !important;
+ padding-right: 0 !important;
+}
+
+/* Specifically target fumadocs nav container */
+.nd-layout-home,
+.nd-layout-docs {
+ padding-left: 0 !important;
+ padding-right: 0 !important;
+ margin-left: 0 !important;
+ margin-right: 0 !important;
+}
+
/* .light .prose :where(a:not([data-card])):not(:where([class~="not-prose"],[class~="not-prose"] *)) {
color: #18181B;
}
diff --git a/app/layout.config.tsx b/app/layout.config.tsx
index 3ad22b15dc0..e3df82b7106 100644
--- a/app/layout.config.tsx
+++ b/app/layout.config.tsx
@@ -140,7 +140,7 @@ export const stats: LinkItemType = {
export const docsMenu: LinkItemType = {
type: 'menu',
- text: 'Docs',
+ text: 'Documentation',
url: '/docs/quick-start',
items: [
{
diff --git a/middleware.ts b/middleware.ts
index 3e1a2c89292..24bca07bd2a 100644
--- a/middleware.ts
+++ b/middleware.ts
@@ -4,6 +4,15 @@ import { NextMiddlewareResult } from "next/dist/server/web/types";
import { NextRequest, NextResponse } from "next/server";
export async function middleware(req: NextRequest) {
+ const pathname = req.nextUrl.pathname;
+
+ // Proxy Mintlify-powered API Reference through our domain in production
+ if (pathname === '/docs/api-reference' || pathname.startsWith('/docs/api-reference/')) {
+ const suffix = pathname === '/docs/api-reference' ? '' : pathname.replace('/docs/api-reference', '');
+ const target = new URL(`https://developers.avacloud.io${suffix}${req.nextUrl.search}`);
+ return NextResponse.rewrite(target);
+ }
+
const response = NextResponse.next();
response.headers.set("Access-Control-Allow-Origin", "*");
response.headers.set(
@@ -18,17 +27,14 @@ export async function middleware(req: NextRequest) {
if (req.method === "OPTIONS") {
return new Response(null, { status: 204 });
}
+
const token = await getToken({ req, secret: process.env.NEXTAUTH_SECRET });
- const pathname = req.nextUrl.pathname;
const isAuthenticated = !!token;
const isLoginPage = pathname === "/login";
const isShowCase = pathname.startsWith("/showcase");
const custom_attributes = token?.custom_attributes as string[] ?? []
- // If not authenticated and trying to access protected routes,
- // preserve the complete URL (including UTM) as callbackUrl
if (!isAuthenticated && !isLoginPage) {
- // Check if it's a protected path
const protectedPaths = [
"/hackathons/registration-form",
"/hackathons/project-submission",
@@ -48,16 +54,13 @@ export async function middleware(req: NextRequest) {
}
if (isAuthenticated) {
-
if (isLoginPage)
return NextResponse.redirect(new URL("/", req.url));
- //TODO Change this line to enable showcase to a different set of users
if (isShowCase && !custom_attributes.includes('showcase'))
return NextResponse.redirect(new URL("/hackathons", req.url))
-
-
}
+
return withAuth(
(authReq: NextRequestWithAuth): NextMiddlewareResult => {
return NextResponse.next();
@@ -68,7 +71,6 @@ export async function middleware(req: NextRequest) {
},
callbacks: {
authorized: ({ token }) => !!token,
-
}
}
)(req as NextRequestWithAuth, {} as any);
@@ -76,6 +78,8 @@ export async function middleware(req: NextRequest) {
export const config = {
matcher: [
+ "/docs/api-reference",
+ "/docs/api-reference/:path*",
"/hackathons/registration-form/:path*",
"/hackathons/project-submission/:path*",
"/showcase/:path*",
diff --git a/next.config.mjs b/next.config.mjs
index 6eaaa1733a8..371d2f79ec6 100644
--- a/next.config.mjs
+++ b/next.config.mjs
@@ -40,10 +40,30 @@ const config = {
protocol: 'https',
hostname: 'cdn.prod.website-files.com',
},
+ {
+ protocol: 'https',
+ hostname: 'developers.avacloud.io',
+ },
],
},
async rewrites() {
return [
+ {
+ source: '/mintlify-assets/:path*',
+ destination: 'https://developers.avacloud.io/mintlify-assets/:path*',
+ },
+ {
+ source: '/_mintlify/:path*',
+ destination: 'https://developers.avacloud.io/_mintlify/:path*',
+ },
+ {
+ source: '/docs/api-reference',
+ destination: 'https://developers.avacloud.io',
+ },
+ {
+ source: '/docs/api-reference/:path*',
+ destination: 'https://developers.avacloud.io/:path*',
+ },
{
source: '/docs/:path*.mdx',
destination: '/llms.mdx/docs/:path*',
@@ -64,6 +84,41 @@ const config = {
},
async redirects() {
return [
+ {
+ source: '/introduction',
+ destination: '/docs/api-reference/introduction',
+ permanent: false,
+ },
+ {
+ source: '/data-api/:path*',
+ destination: '/docs/api-reference/data-api/:path*',
+ permanent: false,
+ },
+ {
+ source: '/webhooks-api/:path*',
+ destination: '/docs/api-reference/webhooks-api/:path*',
+ permanent: false,
+ },
+ {
+ source: '/metrics-api/:path*',
+ destination: '/docs/api-reference/metrics-api/:path*',
+ permanent: false,
+ },
+ {
+ source: '/rpc-api/:path*',
+ destination: '/docs/api-reference/rpc-api/:path*',
+ permanent: false,
+ },
+ {
+ source: '/avalanche-sdk/:path*',
+ destination: '/docs/api-reference/avalanche-sdk/:path*',
+ permanent: false,
+ },
+ {
+ source: '/changelog/:path*',
+ destination: '/docs/api-reference/changelog/:path*',
+ permanent: false,
+ },
{
source: '/codebase-entrepreneur',
destination: '/codebase-entrepreneur-academy',