Project structure

Swift Rust uses a file-based router inspired by Next.js. The directory structure of your project determines the URL structure of your app.

The default layout

If you chose to use a src/ directory in the scaffolder, your app/ lives inside src/. Otherwise it's at the project root.

my-app/
app/
  layout.tsx       # Root layout (wraps every route)
  page.tsx         # Homepage (/)
  loading.tsx      # Loading UI (optional)
  error.tsx        # Error boundary (optional)
  not-found.tsx    # 404 page
  about/
    page.tsx       # /about
  blog/
    page.tsx       # /blog
    [slug]/
      page.tsx     # /blog/:slug (dynamic)
  api/
    posts/
      route.ts     # GET/POST /api/posts
components/
  ui/              # shadcn-style components
  nav.tsx
  footer.tsx
lib/
  utils.ts         # cn() helper
public/
  favicon.svg
  images/
swift-rust.config.json
package.json
tsconfig.json

Special files

Swift Rust recognizes these special filenames inside any route segment:

  • layout.tsx — A layout that wraps the page and any nested routes.
  • page.tsx — The page component. The URL is determined by the directory path.
  • loading.tsx — A loading UI shown while data is being fetched.
  • error.tsx — An error boundary for this segment and its children.
  • not-found.tsx — A 404 page rendered when no route matches.
  • route.ts — A request handler (replaces page.tsx). Exports GET, POST, etc.

Dynamic segments

Wrap a directory name in square brackets to create a dynamic segment. The captured value is passed to your page as params.

app/blog/[slug]/page.tsx
export default function PostPage({
  params,
}: {
  params: { slug: string };
}) {
  return <h1>Post: {params.slug}</h1>;
}

Catch-all routes

Use [...slug] to capture all remaining path segments.

app/docs/[...slug]/page.tsx
export default function CatchAllPage({
  params,
}: {
  params: { slug: string[] };
}) {
  return <h1>Path: {params.slug.join("/")}</h1>;
}

Next steps

Continue to Layouts & pages.