mgd34msu/goodvibes-gemini

vercel

Deploys applications to Vercel including serverless functions, edge functions, environment variables, and CI/CD. Use when deploying Next.js applications, frontend projects, or serverless APIs.

First seen Mar 29, 2026

Installation

$ npx skills add mgd34msu/goodvibes-gemini --skill vercel

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from mgd34msu/goodvibes-gemini · top by installs.

npx skills add mgd34msu/goodvibes-gemini

Browse all from mgd34msu/goodvibes-gemini

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 4
License MIT
Default branch main
Open issues 0
Status Active

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 8,814 B
  • docs SUMMARY.md 206 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 1 installs

SKILL.md

Vercel

The frontend cloud platform for deploying web applications.

Quick Start

Install CLI:

npm i -g vercel

Deploy:

vercel

Deploy to production:

vercel --prod

Project Setup

Connect Git Repository

  1. Go to vercel.com/new
  2. Import repository from GitHub/GitLab/Bitbucket
  3. Configure build settings (auto-detected for most frameworks)
  4. Deploy

vercel.json Configuration

{
  "buildCommand": "npm run build",
  "outputDirectory": "dist",
  "installCommand": "npm install",
  "framework": "nextjs",
  "regions": ["iad1"],
  "functions": {
    "api/**/*.ts": {
      "memory": 1024,
      "maxDuration": 10
    }
  },
  "rewrites": [
    { "source": "/api/:path*", "destination": "/api/:path*" }
  ],
  "redirects": [
    { "source": "/old", "destination": "/new", "permanent": true }
  ],
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        { "key": "X-Frame-Options", "value": "DENY" }
      ]
    }
  ]
}

Environment Variables

Setting Variables

Via Dashboard:

  1. Project Settings > Environment Variables
  2. Add key-value pairs
  3. Select environments (Production, Preview, Development)

Via CLI:

vercel env add MY_VAR
vercel env ls
vercel env pull .env.local

Environment Types

// Production only
NEXT_PUBLIC_API_URL=https://api.example.com

// Preview (PR deployments)
NEXT_PUBLIC_API_URL=https://staging-api.example.com

// Development
NEXT_PUBLIC_API_URL=http://localhost:3001

Using Variables

// Next.js - server side
const apiKey = process.env.API_KEY;

// Next.js - client side (must be prefixed)
const publicUrl = process.env.NEXT_PUBLIC_API_URL;

Serverless Functions

API Routes (Next.js App Router)

// app/api/users/route.ts
import { NextRequest, NextResponse } from 'next/server';

export async function GET(request: NextRequest) {
  const users = await getUsers();
  return NextResponse.json(users);
}

export async function POST(request: NextRequest) {
  const body = await request.json();
  const user = await createUser(body);
  return NextResponse.json(user, { status: 201 });
}

API Routes (Pages Router)

// pages/api/users.ts
import type { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  if (req.method === 'GET') {
    const users = await getUsers();
    return res.json(users);
  }

  if (req.method === 'POST') {
    const user = await createUser(req.body);
    return res.status(201).json(user);
  }

  res.setHeader('Allow', ['GET', 'POST']);
  res.status(405).end(`Method ${req.method} Not Allowed`);
}

Standalone Functions

// api/hello.ts
import type { VercelRequest, VercelResponse } from '@vercel/node';

export default function handler(req: VercelRequest, res: VercelResponse) {
  return res.json({ message: 'Hello from Vercel!' });
}

Function Configuration

// app/api/heavy/route.ts
export const runtime = 'nodejs';
export const maxDuration = 60; // seconds
export const dynamic = 'force-dynamic';

export async function GET() {
  // Long-running operation
}

Edge Functions

Edge Runtime

// app/api/geo/route.ts
import { NextRequest, NextResponse } from 'next/server';

export const runtime = 'edge';

export async function GET(request: NextRequest) {
  const country = request.geo?.country ?? 'Unknown';
  const city = request.geo?.city ?? 'Unknown';

  return NextResponse.json({
    country,
    city,
    message: `Hello from ${city}, ${country}!`,
  });
}

Middleware

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  // Check auth
  const token = request.cookies.get('token');

  if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.redirect(new URL('/login', request.url));
  }

  // Add headers
  const response = NextResponse.next();
  response.headers.set('x-custom-header', 'value');

  return response;
}

export const config = {
  matcher: ['/dashboard/:path*', '/api/:path*'],
};

Caching & ISR

Static Generation with Revalidation

// app/posts/page.tsx
export const revalidate = 3600; // Revalidate every hour

async function getPosts() {
  const res = await fetch('https://api.example.com/posts', {
    next: { revalidate: 3600 },
  });
  return res.json();
}

export default async function PostsPage() {
  const posts = await getPosts();
  return <PostList posts={posts} />;
}

On-Demand Revalidation

// app/api/revalidate/route.ts
import { revalidatePath, revalidateTag } from 'next/cache';
import { NextRequest, NextResponse } from 'next/server';

export async function POST(request: NextRequest) {
  const { path, tag, secret } = await request.json();

  if (secret !== process.env.REVALIDATE_SECRET) {
    return NextResponse.json({ error: 'Invalid secret' }, { status: 401 });
  }

  if (path) {
    revalidatePath(path);
  }

  if (tag) {
    revalidateTag(tag);
  }

  return NextResponse.json({ revalidated: true });
}

Redirects & Rewrites

vercel.json

{
  "redirects": [
    { "source": "/blog/:slug", "destination": "/posts/:slug", "permanent": true },
    { "source": "/old-page", "destination": "/new-page", "statusCode": 301 }
  ],
  "rewrites": [
    { "source": "/api/:path*", "destination": "https://api.example.com/:path*" },
    { "source": "/:path*", "destination": "/index.html" }
  ]
}

Next.js Config

// next.config.js
module.exports = {
  async redirects() {
    return [
      {
        source: '/old-blog/:slug',
        destination: '/blog/:slug',
        permanent: true,
      },
    ];
  },
  async rewrites() {
    return [
      {
        source: '/api/:path*',
        destination: 'https://api.backend.com/:path*',
      },
    ];
  },
};

Deployment

Preview Deployments

# Every push to non-production branch creates preview
git push origin feature-branch
# Creates: feature-branch-abc123.vercel.app

Production Deployment

# Via CLI
vercel --prod

# Via Git (push to main/master)
git push origin main

Rollback

# Via CLI
vercel rollback [deployment-url]

# Via Dashboard
# Deployments > ... > Promote to Production

Monitoring

Analytics

// app/layout.tsx
import { Analytics } from '@vercel/analytics/react';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Analytics />
      </body>
    </html>
  );
}

Speed Insights

import { SpeedInsights } from '@vercel/speed-insights/next';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <SpeedInsights />
      </body>
    </html>
  );
}

Cron Jobs

// vercel.json
{
  "crons": [
    {
      "path": "/api/cron/daily",
      "schedule": "0 0 * * *"
    },
    {
      "path": "/api/cron/hourly",
      "schedule": "0 * * * *"
    }
  ]
}
// app/api/cron/daily/route.ts
import { NextRequest, NextResponse } from 'next/server';

export async function GET(request: NextRequest) {
  const authHeader = request.headers.get('authorization');

  if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) {
    return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
  }

  // Run daily task
  await runDailyTask();

  return NextResponse.json({ success: true });
}

Best Practices

  1. Use environment variables - Never commit secrets
  2. Configure regions - Deploy close to users/data
  3. Enable preview deployments - Test before production
  4. Use ISR for dynamic content - Balance freshness and speed
  5. Add monitoring - Analytics and Speed Insights

Common Mistakes

Mistake Fix
Exposing secrets Use env vars, not code
Large function bundles Split into smaller functions
Missing NEXTPUBLIC prefix Prefix client-side vars
No error handling Add try/catch in functions
Cold start issues Use edge runtime when possible

Reference Files

  • [references/functions.md](references/functions.md) - Function patterns
  • [references/caching.md](references/caching.md) - Caching strategies
  • [references/domains.md](references/domains.md) - Custom domains