From 89e7ee1692f325d3a75163f55ae12a0e68b86a4f Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Tue, 21 Apr 2026 13:32:57 -0700 Subject: [PATCH 1/2] improvement(landing): scope navbar/footer shell to (shell) route group, align scoped 404s with root MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move integrations and models page routes into a `(shell)` route group so the Navbar+Footer layout wraps pages but not `not-found.tsx`. This lets scoped 404s render the same `` + Navbar treatment as the root `/` 404, instead of appearing inside the landing CTA footer. Extract the shared 404 markup into `` so root, integrations, and models 404s share a single source of truth. Route URLs are unchanged — route groups are URL-transparent. Co-Authored-By: Claude Opus 4.7 --- .../(landing)/components/not-found-view.tsx | 40 +++++++++++++++++++ .../components/integration-cta-button.tsx | 0 .../[slug]/components/integration-faq.tsx | 0 .../components/template-card-button.tsx | 0 .../{ => (shell)}/[slug]/loading.tsx | 0 .../{ => (shell)}/[slug]/page.tsx | 6 +-- .../integrations/{ => (shell)}/layout.tsx | 0 .../integrations/{ => (shell)}/page.tsx | 0 .../app/(landing)/integrations/not-found.tsx | 21 +--------- .../[provider]/[model]/loading.tsx | 0 .../[provider]/[model]/opengraph-image.tsx | 0 .../{ => (shell)}/[provider]/[model]/page.tsx | 0 .../{ => (shell)}/[provider]/loading.tsx | 0 .../[provider]/opengraph-image.tsx | 0 .../models/{ => (shell)}/[provider]/page.tsx | 0 .../(landing)/models/{ => (shell)}/layout.tsx | 0 .../models/{ => (shell)}/opengraph-image.tsx | 0 .../(landing)/models/{ => (shell)}/page.tsx | 0 apps/sim/app/(landing)/models/not-found.tsx | 21 +--------- apps/sim/app/not-found.tsx | 34 ++-------------- 20 files changed, 50 insertions(+), 72 deletions(-) create mode 100644 apps/sim/app/(landing)/components/not-found-view.tsx rename apps/sim/app/(landing)/integrations/{ => (shell)}/[slug]/components/integration-cta-button.tsx (100%) rename apps/sim/app/(landing)/integrations/{ => (shell)}/[slug]/components/integration-faq.tsx (100%) rename apps/sim/app/(landing)/integrations/{ => (shell)}/[slug]/components/template-card-button.tsx (100%) rename apps/sim/app/(landing)/integrations/{ => (shell)}/[slug]/loading.tsx (100%) rename apps/sim/app/(landing)/integrations/{ => (shell)}/[slug]/page.tsx (99%) rename apps/sim/app/(landing)/integrations/{ => (shell)}/layout.tsx (100%) rename apps/sim/app/(landing)/integrations/{ => (shell)}/page.tsx (100%) rename apps/sim/app/(landing)/models/{ => (shell)}/[provider]/[model]/loading.tsx (100%) rename apps/sim/app/(landing)/models/{ => (shell)}/[provider]/[model]/opengraph-image.tsx (100%) rename apps/sim/app/(landing)/models/{ => (shell)}/[provider]/[model]/page.tsx (100%) rename apps/sim/app/(landing)/models/{ => (shell)}/[provider]/loading.tsx (100%) rename apps/sim/app/(landing)/models/{ => (shell)}/[provider]/opengraph-image.tsx (100%) rename apps/sim/app/(landing)/models/{ => (shell)}/[provider]/page.tsx (100%) rename apps/sim/app/(landing)/models/{ => (shell)}/layout.tsx (100%) rename apps/sim/app/(landing)/models/{ => (shell)}/opengraph-image.tsx (100%) rename apps/sim/app/(landing)/models/{ => (shell)}/page.tsx (100%) diff --git a/apps/sim/app/(landing)/components/not-found-view.tsx b/apps/sim/app/(landing)/components/not-found-view.tsx new file mode 100644 index 00000000000..69a0f2d6778 --- /dev/null +++ b/apps/sim/app/(landing)/components/not-found-view.tsx @@ -0,0 +1,40 @@ +import Link from 'next/link' +import { getNavBlogPosts } from '@/lib/blog/registry' +import AuthBackground from '@/app/(auth)/components/auth-background' +import { AUTH_PRIMARY_CTA_BASE } from '@/app/(auth)/components/auth-button-classes' +import Navbar from '@/app/(landing)/components/navbar/navbar' + +/** + * Shared 404 view used by every `not-found.tsx` under the landing surface. + * + * Rendered outside the route-group `(shell)` layout so it owns the full + * viewport (Navbar + AuthBackground decoration, no Footer), matching the + * root `/` 404 treatment. + */ +export default async function NotFoundView() { + const blogPosts = await getNavBlogPosts() + return ( + +
+
+ +
+
+
+

+ Page not found +

+

+ The page you're looking for doesn't exist or has been moved. +

+
+ + Return to Home + +
+
+
+
+
+ ) +} diff --git a/apps/sim/app/(landing)/integrations/[slug]/components/integration-cta-button.tsx b/apps/sim/app/(landing)/integrations/(shell)/[slug]/components/integration-cta-button.tsx similarity index 100% rename from apps/sim/app/(landing)/integrations/[slug]/components/integration-cta-button.tsx rename to apps/sim/app/(landing)/integrations/(shell)/[slug]/components/integration-cta-button.tsx diff --git a/apps/sim/app/(landing)/integrations/[slug]/components/integration-faq.tsx b/apps/sim/app/(landing)/integrations/(shell)/[slug]/components/integration-faq.tsx similarity index 100% rename from apps/sim/app/(landing)/integrations/[slug]/components/integration-faq.tsx rename to apps/sim/app/(landing)/integrations/(shell)/[slug]/components/integration-faq.tsx diff --git a/apps/sim/app/(landing)/integrations/[slug]/components/template-card-button.tsx b/apps/sim/app/(landing)/integrations/(shell)/[slug]/components/template-card-button.tsx similarity index 100% rename from apps/sim/app/(landing)/integrations/[slug]/components/template-card-button.tsx rename to apps/sim/app/(landing)/integrations/(shell)/[slug]/components/template-card-button.tsx diff --git a/apps/sim/app/(landing)/integrations/[slug]/loading.tsx b/apps/sim/app/(landing)/integrations/(shell)/[slug]/loading.tsx similarity index 100% rename from apps/sim/app/(landing)/integrations/[slug]/loading.tsx rename to apps/sim/app/(landing)/integrations/(shell)/[slug]/loading.tsx diff --git a/apps/sim/app/(landing)/integrations/[slug]/page.tsx b/apps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsx similarity index 99% rename from apps/sim/app/(landing)/integrations/[slug]/page.tsx rename to apps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsx index 8915a643494..51a6dfa72fe 100644 --- a/apps/sim/app/(landing)/integrations/[slug]/page.tsx +++ b/apps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsx @@ -3,9 +3,9 @@ import Image from 'next/image' import Link from 'next/link' import { notFound } from 'next/navigation' import { SITE_URL } from '@/lib/core/utils/urls' -import { IntegrationCtaButton } from '@/app/(landing)/integrations/[slug]/components/integration-cta-button' -import { IntegrationFAQ } from '@/app/(landing)/integrations/[slug]/components/integration-faq' -import { TemplateCardButton } from '@/app/(landing)/integrations/[slug]/components/template-card-button' +import { IntegrationCtaButton } from '@/app/(landing)/integrations/(shell)/[slug]/components/integration-cta-button' +import { IntegrationFAQ } from '@/app/(landing)/integrations/(shell)/[slug]/components/integration-faq' +import { TemplateCardButton } from '@/app/(landing)/integrations/(shell)/[slug]/components/template-card-button' import { IntegrationIcon } from '@/app/(landing)/integrations/components/integration-icon' import { blockTypeToIconMap } from '@/app/(landing)/integrations/data/icon-mapping' import integrations from '@/app/(landing)/integrations/data/integrations.json' diff --git a/apps/sim/app/(landing)/integrations/layout.tsx b/apps/sim/app/(landing)/integrations/(shell)/layout.tsx similarity index 100% rename from apps/sim/app/(landing)/integrations/layout.tsx rename to apps/sim/app/(landing)/integrations/(shell)/layout.tsx diff --git a/apps/sim/app/(landing)/integrations/page.tsx b/apps/sim/app/(landing)/integrations/(shell)/page.tsx similarity index 100% rename from apps/sim/app/(landing)/integrations/page.tsx rename to apps/sim/app/(landing)/integrations/(shell)/page.tsx diff --git a/apps/sim/app/(landing)/integrations/not-found.tsx b/apps/sim/app/(landing)/integrations/not-found.tsx index b4ca1ec9d64..549bf6aca0f 100644 --- a/apps/sim/app/(landing)/integrations/not-found.tsx +++ b/apps/sim/app/(landing)/integrations/not-found.tsx @@ -1,6 +1,5 @@ import type { Metadata } from 'next' -import Link from 'next/link' -import { AUTH_PRIMARY_CTA_BASE } from '@/app/(auth)/components/auth-button-classes' +import NotFoundView from '@/app/(landing)/components/not-found-view' export const metadata: Metadata = { title: 'Page Not Found', @@ -8,21 +7,5 @@ export const metadata: Metadata = { } export default function IntegrationsNotFound() { - return ( -
-
-

- Page not found -

-

- The page you're looking for doesn't exist or has been moved. -

-
- - Return to Home - -
-
-
- ) + return } diff --git a/apps/sim/app/(landing)/models/[provider]/[model]/loading.tsx b/apps/sim/app/(landing)/models/(shell)/[provider]/[model]/loading.tsx similarity index 100% rename from apps/sim/app/(landing)/models/[provider]/[model]/loading.tsx rename to apps/sim/app/(landing)/models/(shell)/[provider]/[model]/loading.tsx diff --git a/apps/sim/app/(landing)/models/[provider]/[model]/opengraph-image.tsx b/apps/sim/app/(landing)/models/(shell)/[provider]/[model]/opengraph-image.tsx similarity index 100% rename from apps/sim/app/(landing)/models/[provider]/[model]/opengraph-image.tsx rename to apps/sim/app/(landing)/models/(shell)/[provider]/[model]/opengraph-image.tsx diff --git a/apps/sim/app/(landing)/models/[provider]/[model]/page.tsx b/apps/sim/app/(landing)/models/(shell)/[provider]/[model]/page.tsx similarity index 100% rename from apps/sim/app/(landing)/models/[provider]/[model]/page.tsx rename to apps/sim/app/(landing)/models/(shell)/[provider]/[model]/page.tsx diff --git a/apps/sim/app/(landing)/models/[provider]/loading.tsx b/apps/sim/app/(landing)/models/(shell)/[provider]/loading.tsx similarity index 100% rename from apps/sim/app/(landing)/models/[provider]/loading.tsx rename to apps/sim/app/(landing)/models/(shell)/[provider]/loading.tsx diff --git a/apps/sim/app/(landing)/models/[provider]/opengraph-image.tsx b/apps/sim/app/(landing)/models/(shell)/[provider]/opengraph-image.tsx similarity index 100% rename from apps/sim/app/(landing)/models/[provider]/opengraph-image.tsx rename to apps/sim/app/(landing)/models/(shell)/[provider]/opengraph-image.tsx diff --git a/apps/sim/app/(landing)/models/[provider]/page.tsx b/apps/sim/app/(landing)/models/(shell)/[provider]/page.tsx similarity index 100% rename from apps/sim/app/(landing)/models/[provider]/page.tsx rename to apps/sim/app/(landing)/models/(shell)/[provider]/page.tsx diff --git a/apps/sim/app/(landing)/models/layout.tsx b/apps/sim/app/(landing)/models/(shell)/layout.tsx similarity index 100% rename from apps/sim/app/(landing)/models/layout.tsx rename to apps/sim/app/(landing)/models/(shell)/layout.tsx diff --git a/apps/sim/app/(landing)/models/opengraph-image.tsx b/apps/sim/app/(landing)/models/(shell)/opengraph-image.tsx similarity index 100% rename from apps/sim/app/(landing)/models/opengraph-image.tsx rename to apps/sim/app/(landing)/models/(shell)/opengraph-image.tsx diff --git a/apps/sim/app/(landing)/models/page.tsx b/apps/sim/app/(landing)/models/(shell)/page.tsx similarity index 100% rename from apps/sim/app/(landing)/models/page.tsx rename to apps/sim/app/(landing)/models/(shell)/page.tsx diff --git a/apps/sim/app/(landing)/models/not-found.tsx b/apps/sim/app/(landing)/models/not-found.tsx index 7db4e7cbfb8..e034fd58c67 100644 --- a/apps/sim/app/(landing)/models/not-found.tsx +++ b/apps/sim/app/(landing)/models/not-found.tsx @@ -1,6 +1,5 @@ import type { Metadata } from 'next' -import Link from 'next/link' -import { AUTH_PRIMARY_CTA_BASE } from '@/app/(auth)/components/auth-button-classes' +import NotFoundView from '@/app/(landing)/components/not-found-view' export const metadata: Metadata = { title: 'Page Not Found', @@ -8,21 +7,5 @@ export const metadata: Metadata = { } export default function ModelsNotFound() { - return ( -
-
-

- Page not found -

-

- The page you're looking for doesn't exist or has been moved. -

-
- - Return to Home - -
-
-
- ) + return } diff --git a/apps/sim/app/not-found.tsx b/apps/sim/app/not-found.tsx index 73b95cf2caf..74956afdaf1 100644 --- a/apps/sim/app/not-found.tsx +++ b/apps/sim/app/not-found.tsx @@ -1,39 +1,11 @@ import type { Metadata } from 'next' -import Link from 'next/link' -import { getNavBlogPosts } from '@/lib/blog/registry' -import AuthBackground from '@/app/(auth)/components/auth-background' -import { AUTH_PRIMARY_CTA_BASE } from '@/app/(auth)/components/auth-button-classes' -import Navbar from '@/app/(landing)/components/navbar/navbar' +import NotFoundView from '@/app/(landing)/components/not-found-view' export const metadata: Metadata = { title: 'Page Not Found', robots: { index: false, follow: true }, } -export default async function NotFound() { - const blogPosts = await getNavBlogPosts() - return ( - -
-
- -
-
-
-

- Page not found -

-

- The page you're looking for doesn't exist or has been moved. -

-
- - Return to Home - -
-
-
-
-
- ) +export default function NotFound() { + return } From 4bbf211db760ecc52263a7612475012cfddb0b36 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Tue, 21 Apr 2026 13:46:47 -0700 Subject: [PATCH 2/2] fix(landing): convert relative imports to absolute in integrations (shell) page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Build failed because the move into the (shell) route group invalidated relative `./components/...` and `./data/...` imports. CLAUDE.md mandates absolute imports throughout — switching these resolves the Turbopack build errors. Co-Authored-By: Claude Opus 4.7 --- .../app/(landing)/integrations/(shell)/page.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/sim/app/(landing)/integrations/(shell)/page.tsx b/apps/sim/app/(landing)/integrations/(shell)/page.tsx index 3340ba7f271..14daefeeacd 100644 --- a/apps/sim/app/(landing)/integrations/(shell)/page.tsx +++ b/apps/sim/app/(landing)/integrations/(shell)/page.tsx @@ -1,13 +1,13 @@ import type { Metadata } from 'next' import { Badge } from '@/components/emcn' import { SITE_URL } from '@/lib/core/utils/urls' -import { IntegrationCard } from './components/integration-card' -import { IntegrationGrid } from './components/integration-grid' -import { RequestIntegrationModal } from './components/request-integration-modal' -import { blockTypeToIconMap } from './data/icon-mapping' -import integrations from './data/integrations.json' -import { POPULAR_WORKFLOWS } from './data/popular-workflows' -import type { Integration } from './data/types' +import { IntegrationCard } from '@/app/(landing)/integrations/components/integration-card' +import { IntegrationGrid } from '@/app/(landing)/integrations/components/integration-grid' +import { RequestIntegrationModal } from '@/app/(landing)/integrations/components/request-integration-modal' +import { blockTypeToIconMap } from '@/app/(landing)/integrations/data/icon-mapping' +import integrations from '@/app/(landing)/integrations/data/integrations.json' +import { POPULAR_WORKFLOWS } from '@/app/(landing)/integrations/data/popular-workflows' +import type { Integration } from '@/app/(landing)/integrations/data/types' const allIntegrations = integrations as Integration[] const INTEGRATION_COUNT = allIntegrations.length