netlify-deployment-platform

安装量: 78
排名: #9973

安装

npx skills add https://github.com/bobmatnyc/claude-mpm-skills --skill netlify-deployment-platform

Netlify Platform Skill progressive_disclosure: entry_point: summary: "JAMstack deployment platform with serverless functions, forms, and identity" when_to_use: - "When deploying static sites and SPAs" - "When building JAMstack applications" - "When needing serverless functions" - "When requiring built-in forms and auth" quick_start: - "npm install -g netlify-cli" - "netlify login" - "netlify init" - "netlify deploy --prod" token_estimate: entry: 70-85 full: 3800-4800 Netlify Fundamentals Core Concepts Sites: Static sites deployed to Netlify's global CDN Builds: Automated build process triggered by Git commits Deploy Contexts: production, deploy-preview, branch-deploy Atomic Deploys: All-or-nothing deployments with instant rollback Instant Cache Invalidation: CDN cache cleared automatically Platform Benefits Global CDN: Built-in content delivery network Continuous Deployment: Auto-deploy from Git HTTPS by Default: Free SSL certificates Deploy Previews: Preview every pull request Serverless Functions: Backend logic without servers Forms & Identity: Built-in features for common needs Static Site Deployment Supported Frameworks

React (Create React App, Vite)

Build command: npm run build Publish directory: build (CRA) or dist (Vite)

Next.js (Static Export)

Build command: npm run build && npm run export Publish directory: out

Vue.js

Build command: npm run build Publish directory: dist

Gatsby

Build command: gatsby build Publish directory: public

Hugo

Build command: hugo Publish directory: public

Svelte/SvelteKit

Build command: npm run build Publish directory: build

Manual Deployment

Install Netlify CLI

npm install -g netlify-cli

Login to Netlify

netlify login

Initialize site

netlify init

Deploy draft (preview URL)

netlify deploy

Deploy to production

netlify deploy --prod

Deploy with build

netlify deploy --build --prod

netlify.toml Configuration Basic Configuration

netlify.toml

[ build ] # Build command command = "npm run build"

# Publish directory publish = "dist"

# Functions directory functions = "netlify/functions"

Production context

[ context.production ] command = "npm run build:prod"

[ context.production.environment ] NODE_ENV = "production" API_URL = "https://api.example.com"

Deploy Preview context

[ context.deploy-preview ] command = "npm run build:preview"

Branch deploys

[ context.branch-deploy ] command = "npm run build"

Build Settings [ build ] command = "npm run build" publish = "dist"

# Base directory for monorepos base = "packages/web"

# Ignore builds on certain changes ignore = "git diff --quiet $CACHED_COMMIT_REF $COMMIT_REF packages/web"

[ build.environment ] NODE_VERSION = "18" NPM_VERSION = "9" RUBY_VERSION = "3.1"

Advanced Build Configuration [ build ] command = "npm run build" publish = "dist"

# Build processing [ build.processing ] skip_processing = false [ build.processing.css ] bundle = true minify = true [ build.processing.js ] bundle = true minify = true [ build.processing.images ] compress = true

Environment Variables Setting Variables

Via CLI

netlify env:set API_KEY "secret-value" netlify env:set NODE_ENV "production"

List variables

netlify env:list

Import from .env file

netlify env:import .env

Variable Scopes

netlify.toml

[ context.production.environment ] API_URL = "https://api.production.com" ENABLE_ANALYTICS = "true"

[ context.deploy-preview.environment ] API_URL = "https://api.staging.com" ENABLE_ANALYTICS = "false"

[ context.branch-deploy.environment ] API_URL = "https://api.dev.com"

Accessing in Build // During build const apiUrl = process.env.API_URL;

// Client-side (must be prefixed) const publicKey = process.env.REACT_APP_PUBLIC_KEY;

Serverless Functions Function Structure // netlify/functions/hello.js exports.handler = async (event, context) => { return { statusCode: 200, headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ message: 'Hello from Netlify Function', path: event.path, method: event.httpMethod, }), }; };

TypeScript Functions // netlify/functions/api.ts import { Handler, HandlerEvent, HandlerContext } from '@netlify/functions';

interface RequestBody { name: string; email: string; }

export const handler: Handler = async ( event: HandlerEvent, context: HandlerContext ) => { if (event.httpMethod !== 'POST') { return { statusCode: 405, body: 'Method Not Allowed', }; }

const { name, email }: RequestBody = JSON.parse(event.body || '{}');

return { statusCode: 200, body: JSON.stringify({ message: Hello ${name}!, email, }), }; };

Advanced Function Patterns // netlify/functions/database.js const { MongoClient } = require('mongodb');

let cachedDb = null;

async function connectToDatabase() { if (cachedDb) return cachedDb;

const client = await MongoClient.connect(process.env.MONGODB_URI); cachedDb = client.db(); return cachedDb; }

exports.handler = async (event) => { const db = await connectToDatabase(); const users = await db.collection('users').find({}).toArray();

return { statusCode: 200, body: JSON.stringify(users), }; };

Scheduled Functions // netlify/functions/scheduled.js const { schedule } = require('@netlify/functions');

const handler = async () => { console.log('Running scheduled task');

// Your scheduled logic await performBackup();

return { statusCode: 200, }; };

// Run every day at midnight exports.handler = schedule('0 0 * * *', handler);

Background Functions // netlify/functions/background-task.js // Auto-runs in background if response is 200 within 10s exports.handler = async (event) => { // Long-running task await processLargeDataset();

return { statusCode: 200, }; };

// Invoke: POST to /.netlify/functions/background-task

Netlify Forms HTML Form

React Form // ContactForm.jsx import { useState } from 'react';

export default function ContactForm() { const [formData, setFormData] = useState({ name: '', email: '', message: '', });

const handleSubmit = async (e) => { e.preventDefault();

const response = await fetch('/', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: new URLSearchParams({
    'form-name': 'contact',
    ...formData,
  }).toString(),
});

if (response.ok) {
  alert('Thank you for your message!');
}

};

return (

{/ Form fields /}
); }

Form Features

Form Notifications

netlify.toml

[[ plugins ]] package = "@netlify/plugin-emails"

[ plugins.inputs ] formName = "contact" to = "admin@example.com" subject = "New contact form submission"

Netlify Identity Enable Identity // Add to HTML

<script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>

// Initialize if (window.netlifyIdentity) { window.netlifyIdentity.on('init', user => { if (!user) { window.netlifyIdentity.on('login', () => { document.location.href = '/admin/'; }); } }); }

React Integration // useNetlifyIdentity.js import { useEffect, useState } from 'react';

export function useNetlifyIdentity() { const [user, setUser] = useState(null);

useEffect(() => { const netlifyIdentity = window.netlifyIdentity;

netlifyIdentity.on('init', user => setUser(user));
netlifyIdentity.on('login', user => setUser(user));
netlifyIdentity.on('logout', () => setUser(null));

netlifyIdentity.init();

}, []);

return { user, login: () => window.netlifyIdentity.open('login'), logout: () => window.netlifyIdentity.logout(), signup: () => window.netlifyIdentity.open('signup'), }; }

Protected Functions // netlify/functions/protected.js exports.handler = async (event, context) => { const { user } = context.clientContext;

if (!user) { return { statusCode: 401, body: 'Unauthorized', }; }

return { statusCode: 200, body: JSON.stringify({ message: 'Protected data', user: user.email, }), }; };

Redirects and Rewrites _redirects File

_redirects file in publish directory

Redirect with status code

/old-path /new-path 301

Rewrite (proxy)

/api/* https://api.example.com/:splat 200

SPA fallback

/* /index.html 200

Force HTTPS

http://example.com/* https://example.com/:splat 301!

Conditional redirects

/news/* /blog/:splat 302 Country=us

Role-based redirects

/admin/ /admin/dashboard 200! Role=admin /admin/ /unauthorized 401

netlify.toml Redirects [[ redirects ]] from = "/old-path" to = "/new-path" status = 301

[[ redirects ]] from = "/api/*" to = "https://api.example.com/:splat" status = 200 force = true

[[ redirects ]] from = "/*" to = "/index.html" status = 200

[[ redirects ]] from = "/admin/*" to = "/admin/dashboard" status = 200 conditions = {Role = ["admin"]}

Proxy with headers

[[ redirects ]] from = "/proxy/*" to = "https://backend.com/:splat" status = 200 force = true [ redirects.headers ] X-From = "Netlify"

Custom Headers [[ headers ]] for = "/*" [ headers.values ] X-Frame-Options = "DENY" X-XSS-Protection = "1; mode=block" Content-Security-Policy = "default-src 'self'"

[[ headers ]] for = "/assets/*" [ headers.values ] Cache-Control = "public, max-age=31536000, immutable"

Deploy Previews Automatic Preview URLs

netlify.toml

[ context.deploy-preview ] command = "npm run build:preview"

[ context.deploy-preview.environment ] NODE_ENV = "preview" API_URL = "https://api-staging.example.com"

Branch Deploys

Deploy specific branches

[ context.staging ] command = "npm run build:staging"

[ context.staging.environment ] API_URL = "https://api-staging.example.com"

Branch pattern matching

[ context.branch-deploy ] command = "npm run build"

Deploy Notifications

GitHub PR comments

Slack notifications

Email notifications

Configured in Netlify UI

Split Testing (A/B Testing) Configuration

netlify.toml

[[ redirects ]] from = "/*" to = "/version-a/:splat" status = 200 conditions = {Cookie = ["ab_test=a"]} force = true

[[ redirects ]] from = "/*" to = "/version-b/:splat" status = 200 conditions = {Cookie = ["ab_test=b"]} force = true

50/50 split

[[ redirects ]] from = "/*" to = "/version-a/:splat" status = 200! percentage = 50

[[ redirects ]] from = "/*" to = "/version-b/:splat" status = 200!

Edge Functions Deno Runtime // netlify/edge-functions/hello.ts import type { Context } from "https://edge.netlify.com";

export default async (request: Request, context: Context) => { const url = new URL(request.url);

return new Response(Hello from ${url.pathname}, { headers: { "content-type": "text/html" }, }); };

export const config = { path: "/hello" };

Geolocation // netlify/edge-functions/geo.ts import type { Context } from "https://edge.netlify.com";

export default async (request: Request, context: Context) => { const { city, country } = context.geo;

return Response.json({ location: ${city}, ${country}, }); };

Transform Response // netlify/edge-functions/transform.ts import type { Context } from "https://edge.netlify.com";

export default async (request: Request, context: Context) => { const response = await context.next(); const text = await response.text();

// Modify HTML const modified = text.replace( '</body>', '<script>console.log("Injected by edge");</script></body>' );

return new Response(modified, response); };

export const config = { path: "/*" };

Custom Domains and SSL Add Custom Domain

Via CLI

netlify domains:add example.com

DNS Configuration

A record: 75.2.60.5

CNAME: .netlify.app

Verify domain

netlify domains:verify example.com

SSL Certificates

Automatic HTTPS (default)

Free Let's Encrypt certificates

Auto-renewal

Force HTTPS redirect

[[ redirects ]] from = "http://example.com/*" to = "https://example.com/:splat" status = 301 force = true

Analytics Netlify Analytics

Custom Analytics // Track custom events function trackEvent(eventName, data) { fetch('/.netlify/functions/analytics', { method: 'POST', body: JSON.stringify({ event: eventName, ...data }), }); }

trackEvent('button_click', { button: 'signup' });

CLI Advanced Usage Development Server

Run functions locally

netlify dev

Specific port

netlify dev --port 3000

Live session sharing

netlify dev --live

Functions only

netlify functions:serve

Site Management

Link existing site

netlify link

Create new site

netlify sites:create

List sites

netlify sites:list

Site info

netlify status

Open site in browser

netlify open

Deploy Management

List deploys

netlify deploy:list

Rollback to previous deploy

netlify rollback

Cancel deploy

netlify deploy:cancel

Git Integration Continuous Deployment

netlify.toml

[ build ] command = "npm run build" publish = "dist"

Auto-publish on Git push

Production: main/master branch

Previews: all pull requests

Branch deploys: configured branches

Deploy Hooks

Trigger builds via webhook

curl -X POST -d {} https://api.netlify.com/build_hooks/

Scheduled builds (use external cron + webhook)

Best Practices Performance Optimization

Enable processing

[ build.processing ] skip_processing = false

[ build.processing.css ] bundle = true minify = true

[ build.processing.js ] bundle = true minify = true

[ build.processing.images ] compress = true

Asset optimization

[[ headers ]] for = "/assets/*" [ headers.values ] Cache-Control = "public, max-age=31536000, immutable"

Security Headers [[ headers ]] for = "/*" [ headers.values ] X-Frame-Options = "DENY" X-Content-Type-Options = "nosniff" X-XSS-Protection = "1; mode=block" Referrer-Policy = "strict-origin-when-cross-origin" Permissions-Policy = "geolocation=(), microphone=(), camera=()" Content-Security-Policy = """ default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; """

Function Best Practices // Keep functions lightweight // Use connection pooling // Cache external API responses // Set appropriate timeouts // Handle errors gracefully

exports.handler = async (event) => { try { // Set timeout const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 8000);

const response = await fetch(API_URL, {
  signal: controller.signal,
});

clearTimeout(timeout);

return {
  statusCode: 200,
  body: JSON.stringify(await response.json()),
};

} catch (error) { console.error('Function error:', error);

return {
  statusCode: 500,
  body: JSON.stringify({ error: 'Internal server error' }),
};

} };

Build Optimization [ build ] command = "npm run build" publish = "dist"

# Skip builds when not needed ignore = """ git diff --quiet $CACHED_COMMIT_REF $COMMIT_REF -- . ':(exclude)docs/' ':(exclude)*.md' """

Cache dependencies

[ build.environment ] NPM_FLAGS = "--legacy-peer-deps" NODE_OPTIONS = "--max-old-space-size=4096"

Monorepo Support

netlify.toml

[ build ] base = "packages/web" command = "npm run build" publish = "dist"

# Only build when package changes ignore = "git diff --quiet $CACHED_COMMIT_REF $COMMIT_REF packages/web"

Common Patterns SPA with API Proxy [ build ] command = "npm run build" publish = "build" functions = "netlify/functions"

[[ redirects ]] from = "/api/*" to = "/.netlify/functions/:splat" status = 200

[[ redirects ]] from = "/*" to = "/index.html" status = 200

Microsite with Subfolder [[ redirects ]] from = "/blog/*" to = "https://blog.example.com/:splat" status = 200 force = true

Authentication Gateway [[ redirects ]] from = "/app/*" to = "/app/dashboard" status = 200 conditions = {Role = ["user"]}

[[ redirects ]] from = "/app/*" to = "/login" status = 302

Summary: Netlify provides a complete JAMstack platform with static hosting, serverless functions, forms, and identity management. Key strengths include atomic deploys, instant cache invalidation, deploy previews, and built-in CDN. Configure via netlify.toml for builds, redirects, headers, and environment-specific settings. Leverage serverless functions for backend logic, forms for user input, and Edge Functions for edge computing. Best practices include performance optimization, security headers, and efficient build configurations.

返回排行榜