# How to Configure Next.js Specific Settings in open-seo

> Open-seo is built with Vite and Cloudflare Workers not Next.js. Learn how to configure Vite front-end and Cloudflare Worker back-end settings in open-seo.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: how-to-guide
- Published: 2026-08-16

---

**Open‑seo does not use Next.js; it is built with Vite and Cloudflare Workers, so there is no [`next.config.js`](https://github.com/every-app/open-seo/blob/main/next.config.js) or Next.js‑specific configuration inside the repository.** Instead, you configure the Vite front‑end in [`web/vite.config.ts`](https://github.com/every-app/open-seo/blob/main/web/vite.config.ts) and the Cloudflare Worker back‑end in [`worker-configuration.d.ts`](https://github.com/every-app/open-seo/blob/main/worker-configuration.d.ts).

The open‑seo repository by every-app is a full‑stack SEO analysis platform. Its architecture separates concerns: a **React UI bundled by Vite** serves the dashboard, while **Cloudflare Workers** handle API requests and data processing. Because Next.js is not part of this stack, any Next.js‑specific settings must be configured in a separate project that consumes open‑seo as an external service.

## Understanding the open‑seo Architecture

Before attempting configuration, understand how the codebase is organized. This prevents confusion about where settings actually live.

### Front‑End: Vite, Not Next.js

The `web/` directory contains a standard Vite + React application. Key files include:

| File | Purpose |
|------|---------|
| [`web/vite.config.ts`](https://github.com/every-app/open-seo/blob/main/web/vite.config.ts) | Vite build configuration, dev server options, and plugin setup |
| [`web/package.json`](https://github.com/every-app/open-seo/blob/main/web/package.json) | Dependencies and npm scripts for the UI |
| `web/src/` | React components and application logic |

There is no `pages/`, `app/`, or [`next.config.js`](https://github.com/every-app/open-seo/blob/main/next.config.js) anywhere in this folder. The Vite dev server runs on its own port, completely independent of any Next.js development workflow.

### Back‑End: Cloudflare Workers

API logic lives in Cloudflare Workers, not a Node.js server. Configuration happens through:

| File | Purpose |
|------|---------|
| [`worker-configuration.d.ts`](https://github.com/every-app/open-seo/blob/main/worker-configuration.d.ts) | TypeScript declarations for Worker bindings (KV, D1, secrets) |
| [`src/index.ts`](https://github.com/every-app/open-seo/blob/main/src/index.ts) (or similar worker entry) | Request routing and handler logic |
| [`wrangler.toml`](https://github.com/every-app/open-seo/blob/main/wrangler.toml) | Deployment configuration for Cloudflare |

## Where Next.js Fits In (External Integration)

Since open‑seo has no internal Next.js configuration, you have two paths for using it alongside Next.js:

**1. Treat open‑seo as a microservice**

Run open‑seo separately—locally with `npm run dev` in the `web` folder plus Wrangler for the worker, or deployed to Cloudflare. Your Next.js application calls its REST endpoints.

**2. Embed open‑seo UI components**

Import the React components from `web/src/` into your Next.js project. This requires manual transpilation configuration in your own [`next.config.js`](https://github.com/every-app/open-seo/blob/main/next.config.js), not in open‑seo.

## Configuring Equivalent Settings in open‑seo

If you are looking for Next.js‑specific features, here is where to find their open‑seo equivalents:

### Rewrites and Redirects

**Next.js approach:** [`next.config.js`](https://github.com/every-app/open-seo/blob/main/next.config.js) with `async rewrites()` or `async redirects()`

**open‑seo approach:** Handle at the Cloudflare Worker level or your reverse proxy. The Worker in [`src/index.ts`](https://github.com/every-app/open-seo/blob/main/src/index.ts) can route requests conditionally:

```typescript
// In your Cloudflare Worker (src/index.ts or similar)
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url);
    
    // Equivalent to a Next.js rewrite
    if (url.pathname.startsWith('/api/legacy')) {
      const newUrl = new URL(url.pathname.replace('/api/legacy', '/v2'), 'https://new-api.example.com');
      return fetch(newUrl.toString(), request);
    }
    
    return handleRequest(request, env);
  }
} satisfies ExportedHandler<Env>;

```

### Environment Variables

**Next.js approach:** `.env.local`, `process.env.NEXT_PUBLIC_*`

**open‑seo approach:** Two separate systems

For the **Vite front‑end**, prefix variables with `VITE_` in `.env` and access via `import.meta.env`:

```typescript
// web/src/config/api.ts
const API_ENDPOINT = import.meta.env.VITE_API_URL ?? 'https://api.open-seo.example.com';

```

For **Cloudflare Workers**, add secrets via Wrangler and declare them in [`worker-configuration.d.ts`](https://github.com/every-app/open-seo/blob/main/worker-configuration.d.ts):

```typescript
// worker-configuration.d.ts
interface Env {
  DATAFORSEO_API_KEY: string;
  D1_DATABASE: D1Database;
  SEO_KV: KVNamespace;
}

```

Access in your worker:

```typescript
// src/handlers/seo-analysis.ts
export async function analyzeKeywords(query: string, env: Env) {
  const response = await fetch('https://api.dataforseo.com/v3/keywords', {
    headers: {
      'Authorization': `Basic ${btoa(env.DATAFORSEO_API_KEY + ':')}`
    },
    body: JSON.stringify({ keyword: query })
  });
  return response.json();
}

```

### Image Optimization

**Next.js approach:** `next/image` with automatic optimization

**open‑seo approach:** Use Cloudflare Images or a custom Vite plugin. No built‑in equivalent exists. Configure in [`web/vite.config.ts`](https://github.com/every-app/open-seo/blob/main/web/vite.config.ts):

```typescript
// web/vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { imagetools } from 'vite-imagetools';

export default defineConfig({
  plugins: [
    react(),
    imagetools({
      defaultDirectives: new URLSearchParams({
        width: '800;1200;1600',
        format: 'avif;webp;jpeg'
      })
    })
  ],
  build: {
    assetsInlineLimit: 4096
  }
});

```

### API Routes

**Next.js approach:** `pages/api/*.ts` or `app/api/*`

**open‑seo approach:** Cloudflare Worker handlers in `src/`:

```typescript
// src/routes/keyword-research.ts
import type { Env } from '../types';

export async function handleKeywordResearch(request: Request, env: Env): Promise<Response> {
  if (request.method !== 'POST') {
    return new Response('Method not allowed', { status: 405 });
  }
  
  const { query } = await request.json();
  const results = await env.D1_DATABASE.prepare(
    'SELECT * FROM keywords WHERE term = ?'
  ).bind(query).all();
  
  return Response.json(results);
}

```

## Integrating open‑seo with Your Next.js Project

When you need Next.js and open‑seo together, configure them as separate services. Your Next.js [`next.config.js`](https://github.com/every-app/open-seo/blob/main/next.config.js) only controls your application; it cannot modify open‑seo behavior.

### Example: Next.js API Route Calling open‑seo

```typescript
// pages/api/seo-analysis.ts (in YOUR Next.js project)
import type { NextApiRequest, NextApiResponse } from 'next';

const OPEN_SEO_ENDPOINT = process.env.OPEN_SEO_ENDPOINT;

if (!OPEN_SEO_ENDPOINT) {
  throw new Error('OPEN_SEO_ENDPOINT environment variable is required');
}

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  if (req.method !== 'POST') {
    return res.status(405).json({ error: 'Method not allowed' });
  }

  try {
    const openSeoResponse = await fetch(`${OPEN_SEO_ENDPOINT}/v1/keyword-research`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': process.env.OPEN_SEO_API_KEY!
      },
      body: JSON.stringify({ query: req.body.query })
    });

    if (!openSeoResponse.ok) {
      throw new Error(`Open‑seo API error: ${openSeoResponse.status}`);
    }

    const data = await openSeoResponse.json();
    return res.status(200).json(data);
  } catch (error) {
    console.error('Failed to call open‑seo:', error);
    return res.status(500).json({ error: 'Analysis failed' });
  }
}

```

### Example: Redirecting to open‑seo UI from Next.js

```javascript
// next.config.js (in YOUR Next.js project)
/** @type {import('next').NextConfig} */
const nextConfig = {
  async redirects() {
    return [
      {
        source: '/seo-dashboard',
        destination: 'https://open-seo.yourdomain.com',
        permanent: false
      }
    ];
  },
  
  // Proxy API calls to open‑seo worker during development
  async rewrites() {
    return [
      {
        source: '/api/seo/:path*',
        destination: `${process.env.OPEN_SEO_ENDPOINT}/:path*`
      }
    ];
  }
};

module.exports = nextConfig;

```

## Summary

- **open‑seo uses Vite and Cloudflare Workers**, not Next.js—there is no [`next.config.js`](https://github.com/every-app/open-seo/blob/main/next.config.js) to edit in the repository.
- Configure **front‑end settings** in [`web/vite.config.ts`](https://github.com/every-app/open-seo/blob/main/web/vite.config.ts) and **back‑end settings** in [`worker-configuration.d.ts`](https://github.com/every-app/open-seo/blob/main/worker-configuration.d.ts) and your Worker handlers.
- **Next.js integration happens externally**: run open‑seo as a separate service and call its API from your Next.js application.
- For equivalent Next.js features (rewrites, redirects, image optimization), implement them at the Cloudflare Worker level or in your own project's Next.js configuration.

## Frequently Asked Questions

### Does open‑seo support Next.js App Router?

No. open‑seo does not use Next.js at all. Its front‑end is a React application built with Vite. If you need App Router features like server components or nested layouts, implement them in your own Next.js project that consumes open‑seo's API.

### Can I deploy open‑seo to Vercel?

You can deploy the Vite front‑end to Vercel as a static site, but the API requires Cloudflare Workers due to its reliance on D1, KV, and other Workers-specific bindings. There is no first-class Vercel deployment path for the full stack.

### How do I handle environment variables in development?

Create a `.env` file in the `web/` directory for Vite variables (prefix with `VITE_`) and use `wrangler secret put` for Cloudflare Worker secrets. See [`docs/LOCAL_DEVELOPMENT.md`](https://github.com/every-app/open-seo/blob/main/docs/LOCAL_DEVELOPMENT.md) for the complete setup workflow.

### Where is the open‑seo API documented?

The OpenAPI specification and example calls are located in the `scripts/` folder. Run the examples with `npx tsx scripts/example-call.ts` after configuring your environment variables.