0 / 0
Skip to content

Integrating Fastify with VitePress

Fastify is a modern, fast, and low overhead web framework for Node.js. In this post, we’ll explore how to integrate Fastify with VitePress using a custom Vite plugin, providing a high-performance server-side solution for your documentation site.

Why Choose Fastify?

Fastify offers several advantages over traditional web frameworks:

  • Performance: One of the fastest web frameworks available
  • TypeScript Support: Built-in TypeScript support
  • Schema-based Validation: JSON Schema validation out of the box
  • Plugin System: Highly extensible through plugins
  • Low Overhead: Minimal impact on your application’s performance

Setting Up the Fastify Plugin

Let’s create a custom Vite plugin that will integrate Fastify with our VitePress application.

1. Create the Fastify Plugin

Create a new file docs/.vitepress/plugins/fastify.js:

javascript
import Fastify from 'fastify'
import cors from '@fastify/cors'

export function createFastifyPlugin(options = {}) {
  const {
    corsOptions = {
      origin: '*',
      methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
      allowedHeaders: ['Content-Type', 'Authorization'],
    },
  } = options

  return {
    name: 'vite-plugin-fastify',
    async configureServer(server) {
      const fastify = Fastify({
        logger: true,
      })

      // Enable CORS
      await fastify.register(cors, corsOptions)

      // Example route
      fastify.get('/api/hello', async (request, reply) => {
        return { message: 'Hello from Fastify!' }
      })

      // Example POST route
      fastify.post('/api/submit', async (request, reply) => {
        const data = request.body
        return { success: true, data }
      })

      // Use Fastify as middleware in Vite’s server
      server.middlewares.use(async (req, res, next) => {
        // Skip Fastify handling for non-API routes
        if (!req.url.startsWith('/api')) {
          return next()
        }

        try {
          const response = await fastify.inject({
            method: req.method,
            url: req.url,
            headers: req.headers,
            payload: req.body,
          })

          // Set response headers
          Object.entries(response.headers).forEach(([key, value]) => {
            res.setHeader(key, value)
          })

          // Set status code
          res.statusCode = response.statusCode

          // Send response
          res.end(response.payload)
        } catch (error) {
          next(error)
        }
      })
    },
  }
}

2. Configure VitePress

Update your docs/vite.config.js to use the Fastify plugin:

javascript
import { createFastifyPlugin } from './.vitepress/plugins/fastify'

export default {
  plugins: [
    createFastifyPlugin({
      corsOptions: {
        origin: 'http://localhost:5173', // VitePress default port
        methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
        allowedHeaders: ['Content-Type', 'Authorization'],
      },
    }),
  ],
}

How It Works

The integration works by:

  1. Creating a custom Vite plugin that initializes a Fastify application
  2. Using Vite’s middleware system to integrate Fastify with the development server
  3. Running Fastify routes on the same port as VitePress (default: 5173)

The key to making this work is the middleware implementation:

javascript
server.middlewares.use(async (req, res, next) => {
  // Skip Fastify handling for non-API routes
  if (!req.url.startsWith('/api')) {
    return next()
  }

  try {
    const response = await fastify.inject({
      method: req.method,
      url: req.url,
      headers: req.headers,
      payload: req.body,
    })

    // Set response headers
    Object.entries(response.headers).forEach(([key, value]) => {
      res.setHeader(key, value)
    })

    // Set status code
    res.statusCode = response.statusCode

    // Send response
    res.end(response.payload)
  } catch (error) {
    next(error)
  }
})

This implementation:

  • Only handles routes that start with /api
  • Properly forwards all other routes to VitePress
  • Correctly sets response headers and status codes
  • Handles errors appropriately

Testing the Integration

  1. Start your VitePress development server:
bash
npm run docs:dev
  1. You should now be able to:
    • Visit your VitePress site at http://localhost:5173
    • Access the Fastify API endpoint at http://localhost:5173/api/hello

You should receive a JSON response:

json
{
  "message": "Hello from Fastify!"
}

Adding Custom Routes

You can add your own routes by modifying the createFastifyPlugin function. Here’s an example of adding a POST endpoint with schema validation:

javascript
fastify.post('/api/submit', {
  schema: {
    body: {
      type: 'object',
      required: ['name', 'email'],
      properties: {
        name: { type: 'string' },
        email: { type: 'string', format: 'email' }
      }
    }
  }
}, async (request, reply) => {
  const data = request.body
  return { success: true, data }
})

Benefits of Using Fastify

  1. Performance: Fastify is one of the fastest web frameworks available
  2. Schema Validation: Built-in JSON Schema validation for request/response
  3. TypeScript Support: Excellent TypeScript support out of the box
  4. Plugin Ecosystem: Rich ecosystem of plugins for various functionalities
  5. Developer Experience: Great developer experience with detailed error messages

Considerations

  • This setup is primarily for development. For production, you might want to consider:
    • Running Fastify as a separate service
    • Using a reverse proxy (like Nginx)
    • Implementing proper security measures
  • Remember that VitePress is still a static site generator, so this integration is most useful during development or when you need specific server-side functionality

Conclusion

Integrating Fastify with VitePress using a custom Vite plugin provides a high-performance way to add server-side functionality to your documentation site. This approach combines the simplicity of VitePress with the speed and features of Fastify.

Remember to check out the VitePress documentation and Fastify documentation for more information about both technologies.