# Preview changes

> Learn how to preview documentation changes with Fern using local development servers and shareable preview links before publishing.

Fern offers two ways to preview documentation changes:

* **[Local development](#local-development)**: Fast iteration with hot reload, best for active development
* **[Preview links](#preview-links)**: Shareable URLs for reviews and collaboration

<Info title="Prerequisites">
  Install the following:

  * Node.js version 18 or higher
  * [The Fern CLI](/learn/cli-api-reference/cli-reference/overview#install-fern-cli)
</Info>

## Local development

[Run a local preview server](/learn/cli-api-reference/cli-reference/commands#fern-docs-dev) to view documentation changes instantly with hot reload. Offline access is available after the first online run.

```bash
 # Start preview server (from directory containing fern folder)
  fern docs dev

  # Or use a custom port
  fern docs dev --port 3002
```

Your documentation will be available at `http://localhost:3000` (default) or the port you specified. If you attempt to run Fern on a port that's already in use, it will use the next available port.

<Note>
  Some features are disabled in local development:

  * Search
  * SEO (favicon, auto-generated meta tags, etc.)
  * Authentication
</Note>

## Preview links

Generate shareable preview URLs to review and collaborate on documentation changes before publishing. Each preview link includes a unique UUID and isn't indexed by search engines. Links don't expire.

```bash
fern generate --docs --preview
```

```bash Example output
[docs]: Found 0 errors and 1 warnings. Run fern check --warnings to print out the warnings.
[docs]: Published docs to https://fern-preview-c973a36e-337b-44f5-ab83-aab.docs.buildwithfern.com/learn
┌─
│ ✓  docs.example.com
└─
```

### Automate with GitHub Actions

Generate preview links automatically for every pull request by adding a GitHub Actions workflow. [Add your `FERN_TOKEN` to the repository secrets](/learn/cli-api-reference/cli-reference/commands#fern-token) before using these workflows.

<CodeBlock title=".github/workflows/preview-docs.yml">
  ```yaml
  name: Preview Docs

  on:
    pull_request

  jobs:
    run:
      runs-on: ubuntu-latest
      permissions: write-all
      steps:
        - name: Checkout repository
          uses: actions/checkout@v4

        - name: Install Fern
          run: npm install -g fern-api

        - name: Generate preview URL
          env:
            FERN_TOKEN: ${{ secrets.FERN_TOKEN }}
          run: |
            OUTPUT=$(fern generate --docs --preview 2>&1) || true
            echo "$OUTPUT"
            URL=$(echo "$OUTPUT" | grep -oP 'Published docs to \K.*(?= \()')
            echo "🌿 Preview your docs: $URL" > preview_url.txt

        - name: Comment URL in PR
          uses: thollander/actions-comment-pull-request@v2.4.3
          with:
            filePath: preview_url.txt
  ```
</CodeBlock>

<Accordion title="For repositories that accept pull requests from forks">
  If your repository accepts contributions from forks, use `pull_request_target` instead of `pull_request` to allow the workflow to access your `FERN_TOKEN` secret:

  <CodeBlock title=".github/workflows/preview-docs.yml">
    ```yaml
    name: Preview Docs

    on:
      pull_request_target:
        branches:
          - main

    jobs:
      run:
        runs-on: ubuntu-latest
        permissions:
          pull-requests: write
          contents: read
        steps:
          - name: Checkout repository
            uses: actions/checkout@v4

          - name: Install Fern
            run: npm install -g fern-api

          - name: Checkout PR
            run: |
              git fetch origin pull/${{ github.event.pull_request.number }}/head:pr-${{ github.event.pull_request.number }}
              git checkout pr-${{ github.event.pull_request.number }}

          - name: Generate preview URL
            env:
              FERN_TOKEN: ${{ secrets.FERN_TOKEN }}
            run: |
              OUTPUT=$(fern generate --docs --preview 2>&1) || true
              echo "$OUTPUT"
              URL=$(echo "$OUTPUT" | grep -oP 'Published docs to \K.*(?= \()')
              echo "🌿 Preview your docs: $URL" > preview_url.txt

          - name: Comment URL in PR
            uses: thollander/actions-comment-pull-request@v2.4.3
            with:
              filePath: preview_url.txt
    ```
  </CodeBlock>
</Accordion>