Netlify generates unique URLs for each deployment, with special patterns for functions, forms, and identity. Understanding these helps with testing and integration.
Key Takeaways
- 1Deploy previews get unique {deploy-id}--{site}.netlify.app URLs
- 2Functions are available at /.netlify/functions/{name}
- 3Redirect rules in _redirects or netlify.toml
- 4Branch deploys use {branch}--{site}.netlify.app pattern
- 5Split testing assigns visitors to branches via cookie
Netlify's URL structure is designed around the concept of immutable deploys. Every push creates a new deployment with a unique URL, making it easy to test changes, share previews, and roll back if something goes wrong.
“Netlify generates a unique deploy URL for each deploy, making it easy to share and preview changes before they go live.”
URL Types
Netlify generates several URL types for different purposes. Understanding these patterns helps you share the right links with your team and configure webhooks correctly.
| Type | Pattern | Example |
|---|---|---|
| Production | {site}.netlify.app | mysite.netlify.app |
| Deploy preview | {deploy-id}--{site}.netlify.app | abc123--mysite.netlify.app |
| Branch deploy | {branch}--{site}.netlify.app | staging--mysite.netlify.app |
| Functions | /.netlify/functions/{name} | /.netlify/functions/hello |
| Custom domain | your-domain.com | www.example.com |
Functions use a special /.netlify/functions/ path prefix, while all other URLs follow the pattern of identifier, double-dash, and site name. This makes Netlify URLs easy to identify and parse.
Deployment URLs
Each deployment URL pattern serves a specific purpose. Deploy previews are immutable snapshots, branch deploys update with each push to that branch, and PR previews make code review easier.
# Netlify deployment URL patterns
# Production (latest from production branch)
https://{site-name}.netlify.app
# Unique deploy preview (immutable)
https://{deploy-id}--{site-name}.netlify.app
# Branch deploy
https://{branch-name}--{site-name}.netlify.app
# Pull request preview
https://deploy-preview-{pr-number}--{site-name}.netlify.app
# Examples
https://my-gatsby-site.netlify.app
https://6123abc456def--my-gatsby-site.netlify.app
https://staging--my-gatsby-site.netlify.app
https://deploy-preview-42--my-gatsby-site.netlify.app
# With custom subdomain
https://docs.myapp.com -> Branch: docs
https://preview.myapp.com -> Latest deploy previewThe deploy ID in preview URLs is immutable—bookmarking that URL will always show that exact deployment. Branch deploy URLs update with each push, making them ideal for staging environments.
Function URLs
Netlify Functions are serverless functions that run on AWS Lambda. They are accessible at /.netlify/functions/ followed by the function name (matching the filename without extension).
// Netlify Functions are at /.netlify/functions/{name}
// netlify/functions/hello.js
exports.handler = async (event, context) => {
const url = new URL(event.rawUrl);
const name = url.searchParams.get('name') || 'World';
return {
statusCode: 200,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ message: `Hello, ${name}!` })
};
};
// Accessed at:
// https://mysite.netlify.app/.netlify/functions/hello?name=John
// With path parameters (Netlify Functions v2)
// netlify/functions/users/[id].js
export default async (request, context) => {
const { id } = context.params;
return Response.json({ userId: id });
};
// URL: /.netlify/functions/users/123
// Background functions (async)
// netlify/functions/process-background.js
// URL: /.netlify/functions/process-background
// Returns 202 Accepted immediatelyFunctions receive the full request URL in event.rawUrl, making it easy to parse query parameters. Background functions return immediately with a 202 status, running asynchronously for long-running tasks.
Redirect Rules
Netlify's redirect rules are powerful and flexible. You can define them in a _redirects file or netlify.toml. The syntax supports placeholders, conditions, and proxy behavior.
# _redirects file
# Basic redirect
/old-page /new-page 301
# Splat matching
/blog/* /posts/:splat 301
/docs/* https://docs.example.com/:splat 200
# Proxy (shadow)
/api/* https://api.example.com/:splat 200
# Query string handling
/search q=:query /results?query=:query 301
# Country-based redirect
/store/* /store/us/:splat 302 Country=us
/store/* /store/eu/:splat 302 Country=de,fr,nl
# Role-based redirect (with Netlify Identity)
/admin/* /login 302! Role=admin
# SPA fallback
/* /index.html 200
# Force HTTPS
http://example.com/* https://example.com/:splat 301!The :splat placeholder captures everything after the asterisk. Status 200 creates a proxy (rewrite), while 301/302 creates visible redirects. The ! suffix forces the redirect even for existing files.
netlify.toml Configuration
For more complex configurations, use netlify.toml. This TOML file supports environment-specific settings, header configuration, and redirect rules with full syntax highlighting in your editor.
# netlify.toml
[build]
publish = "dist"
command = "npm run build"
# Redirects
[[redirects]]
from = "/api/*"
to = "https://api.example.com/:splat"
status = 200
force = true
[[redirects]]
from = "/old-path"
to = "/new-path"
status = 301
# Headers
[[headers]]
for = "/api/*"
[headers.values]
Access-Control-Allow-Origin = "*"
Cache-Control = "no-cache"
[[headers]]
for = "/static/*"
[headers.values]
Cache-Control = "public, max-age=31536000"
# Environment-specific redirects
[context.production]
environment = { API_URL = "https://api.example.com" }
[context.deploy-preview]
environment = { API_URL = "https://staging-api.example.com" }
[context.branch-deploy]
environment = { API_URL = "https://dev-api.example.com" }The [context] blocks let you set different environment variables for production, preview, and branch deploys. This is useful for pointing to different API backends or enabling debug features.
Edge Functions
Edge Functions run at the CDN edge, closer to your users than regular serverless functions. They are ideal for URL-based routing, authentication, and personalization that needs to happen before the page loads.
// netlify/edge-functions/transform.js
export default async (request, context) => {
const url = new URL(request.url);
// URL-based routing
if (url.pathname.startsWith('/api/')) {
// Modify request headers
const modifiedRequest = new Request(request, {
headers: new Headers({
...Object.fromEntries(request.headers),
'X-Custom-Header': 'value'
})
});
return context.next(modifiedRequest);
}
// URL rewriting
if (url.pathname === '/pricing') {
const country = context.geo.country?.code || 'US';
url.pathname = `/pricing/${country.toLowerCase()}`;
return context.rewrite(url);
}
// Redirect
if (url.pathname === '/dashboard' && !context.cookies.get('session')) {
return Response.redirect(new URL('/login', request.url));
}
return context.next();
};
export const config = {
path: ["/*"]
};Edge Functions can modify requests, add headers, rewrite URLs, or redirect users. The context object provides geolocation data and cookie access for personalization decisions.
Form Handling URLs
Netlify Forms captures form submissions without requiring a backend. Add the data-netlify="true" attribute to enable automatic form handling, with submissions stored in your Netlify dashboard.
<!-- Netlify Forms -->
<form name="contact" method="POST" data-netlify="true">
<input type="hidden" name="form-name" value="contact" />
<input type="text" name="name" />
<input type="email" name="email" />
<button type="submit">Submit</button>
</form>
<!-- Form posts to same URL by default -->
<!-- Or specify action -->
<form name="contact" action="/thank-you" method="POST" data-netlify="true">
...
</form>
<!-- AJAX form submission -->
<script>
fetch('/', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
'form-name': 'contact',
'name': 'John',
'email': 'john@example.com'
})
});
</script>
<!-- Form submission webhook (netlify.toml) -->
<!-- [build]
[build.processing]
[build.processing.form_submission]
webhook = "https://yourapp.com/webhooks/netlify/form" -->For AJAX submissions, POST to the current page URL with the form-name field included. You can configure a webhook to receive submissions in real-time for integration with other services.
Netlify API URLs
Netlify provides a comprehensive REST API for managing sites, deploys, forms, and functions programmatically. This is useful for building custom dashboards, deployment automation, or content management integrations.
// Netlify API
const baseUrl = 'https://api.netlify.com/api/v1';
// Common endpoints
const endpoints = {
// Sites
listSites: '/sites',
getSite: '/sites/{site_id}',
// Deploys
listDeploys: '/sites/{site_id}/deploys',
getDeploy: '/deploys/{deploy_id}',
createDeploy: '/sites/{site_id}/deploys',
// Forms
listForms: '/sites/{site_id}/forms',
listSubmissions: '/forms/{form_id}/submissions',
// Functions
listFunctions: '/sites/{site_id}/functions'
};
// Example: List deploys
const response = await fetch(`${baseUrl}/sites/${siteId}/deploys`, {
headers: {
'Authorization': `Bearer ${token}`
}
});
// Get deploy by URL
const deploy = await fetch(`${baseUrl}/deploys?url=${deployUrl}`, {
headers: {
'Authorization': `Bearer ${token}`
}
});API requests require a personal access token, which you can create in your Netlify account settings. The API follows REST conventions with clear endpoint patterns for each resource type.