---
title: Manual Installation
description: Create a new fumadocs project from scratch.
---

> Make sure to read the [Quick Start](/docs/ui) guide first.

## Getting Started

Create a new Next.js application with `create-next-app`, and install required packages.

```package-install
fumadocs-ui fumadocs-core
```

### Content Source

You can choose a **content source** you prefer.

There is a list of supported sources:

- [Setup Fumadocs MDX](/docs/mdx)
- [Setup Content Collections](/docs/headless/content-collections)

You have to configure the library correctly following their setup guide before continuing.

Make sure to create a `source.ts` file for content adapters, this allows Fumadocs to interact with your content source through a unified interface.

```json doc-gen:file
{
  "file": "../../examples/next-mdx/lib/source.ts",
  "codeblock": {
    "meta": "title=\"lib/source.ts\""
  }
}
```

### Root Layout

Wrap the entire application inside [Root Provider](/docs/ui/layouts/root-provider), and add required styles to `body`.

```tsx
import { RootProvider } from 'fumadocs-ui/provider';
import type { ReactNode } from 'react';

export default function Layout({ children }: { children: ReactNode }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body
        // you can use Tailwind CSS too
        style={{
          display: 'flex',
          flexDirection: 'column',
          minHeight: '100vh',
        }}
      >
        <RootProvider>{children}</RootProvider>
      </body>
    </html>
  );
}
```

### Styles

Setup Tailwind CSS on your Next.js app, and add the official Tailwind CSS plugin.

```json doc-gen:file
{
  "file": "./content/docs/example/tailwind.config.js",
  "codeblock": {
    "meta": "title=\"tailwind.config.js\""
  }
}
```

> It doesn't come with a default font, you may choose one from `next/font`.

### Layout

Create a `app/layout.config.tsx` file to put the shared options for our layouts.

```json doc-gen:file
{
  "file": "../../examples/next-mdx/app/layout.config.tsx",
  "codeblock": {
    "meta": "title=\"app/layout.config.tsx\""
  }
}
```

Create a folder `/app/docs` for our docs, and give it a proper layout.

```json doc-gen:file
{
  "file": "../../examples/next-mdx/app/docs/layout.tsx",
  "codeblock": {
    "meta": "title=\"app/docs/layout.tsx\""
  }
}
```

> `pageTree` refers to Page Tree, it should be provided by your content source.

### Page

Create a catch-all route `/app/docs/[[...slug]]` for docs pages.

In the page, wrap your content in the [Page](/docs/ui/layouts/page) component.
It may vary depending on your content source. You should configure static rendering with `generateStaticParams` and metadata with `generateMetadata`.

<Tabs groupId='content-source' items={['Fumadocs MDX', 'Content Collections']}>

```json doc-gen:file
{
  "file": "../../examples/next-mdx/app/docs/[[...slug]]/page.tsx",
  "codeblock": {
    "meta": "title=\"app/docs/[[...slug]]/page.tsx\" tab=\"Fumadocs MDX\""
  }
}
```

```json doc-gen:file
{
  "file": "../../examples/content-collections/app/docs/[[...slug]]/page.tsx",
  "codeblock": {
    "meta": "title=\"app/docs/[[...slug]]/page.tsx\" tab=\"Content Collections\""
  }
}
```

</Tabs>

### Search

Use the default document search based on Orama.

<Tabs groupId='content-source' items={['Fumadocs MDX', 'Content Collections']}>

```json doc-gen:file
{
  "file": "../../examples/next-mdx/app/api/search/route.ts",
  "codeblock": {
    "meta": "title=\"app/api/search/route.ts\" tab=\"Fumadocs MDX\""
  }
}
```

```json doc-gen:file
{
  "file": "../../examples/content-collections/app/api/search/route.ts",
  "codeblock": {
    "meta": "title=\"app/api/search/route.ts\" tab=\"Content Collections\""
  }
}
```

</Tabs>

Learn more about [Document Search](/docs/headless/search).

### Done

You can start the dev server and create MDX files.

```mdx title="content/docs/index.mdx"
---
title: Hello World
---

## Introduction

I love Anime.
```

#### Content

See the docs of your content source (e.g. Fumadocs MDX) to customise how content are processed.

#### Routing

See [Organizing Pages](/docs/ui/page-conventions) for customising routing.

#### Other Pages

You can use [Home Layout](/docs/ui/layouts/home-layout) for other pages of the site.
It includes the theme toggle and global navigation links.

### Deploying

It should work out-of-the-box with Vercel & Netlify.

#### Docker Deployment

If you want to deploy your Fumadocs app using Docker with **Fumadocs MDX configured**, make sure to add the `source.config.ts` file to the `WORKDIR` in the Dockerfile.
The following snippet is taken from the official [Next.js Dockerfile Exmaple](https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile):

```zsh title="Dockerfile"
WORKDIR /app

# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* .npmrc* source.config.ts ./
```

This ensures Fumadocs MDX can access your configuration file during builds.
