# 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 Install the following: * Node.js version 18 or higher * [The Fern CLI](/learn/cli-api-reference/cli-reference/overview#install-fern-cli) ## 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. Some features are disabled in local development: * Search * SEO (favicon, auto-generated meta tags, etc.) * Authentication ## 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. ```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 ``` 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: ```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 ```