Preview Deploys
CreatedApr 4, 2026Takeshi Takatsudo
Per-PR preview deployments on Cloudflare Pages
How Preview Deploys Work
When you deploy with a non-main branch name, Cloudflare Pages creates a preview deployment with a unique URL:
https://<branch>.<account>-<project>.pages.dev
For PR-based previews, use the PR number as the branch:
npx wrangler@4 pages deploy deploy \
--project-name=my-site \
--branch="pr-${PR_NUMBER}" \
--commit-hash="${GITHUB_SHA}" \
--commit-message="Preview: PR #${PR_NUMBER}"
The preview URL becomes:
https://pr-42.takazudo-my-site.pages.dev
Preview URL Pattern
The URL format is:
https://<branch-slug>.<account-slug>-<project-name>.pages.dev
Where:
<branch-slug>is the--branchvalue (sanitized)<account-slug>is derived from your Cloudflare account<project-name>is the--project-namevalue
📝 Note
The <account-slug> part is auto-generated by Cloudflare. Check your Pages dashboard to see the exact subdomain format for your account.
Posting Preview URL to PR
Use actions/github-script to post or update a comment with the preview URL:
- name: Comment preview URL on PR
uses: actions/github-script@v8
env:
DEPLOY_URL: ${{ steps.cf-deploy.outputs.deploy_url }}
with:
script: |
const deployUrl = process.env.DEPLOY_URL;
const prNumber = context.issue.number;
const marker = '<!-- cf-preview-pr -->';
const body = [
marker,
`## Cloudflare Pages Preview`,
'',
`Preview deployment is ready.`,
'',
`| | URL |`,
`|---|---|`,
`| Preview | ${deployUrl} |`,
'',
`Built from commit: \`${context.sha.substring(0, 7)}\``,
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
});
const existing = comments.find(c => c.body.includes(marker));
if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body,
});
}
The HTML comment marker (<!-- cf-preview-pr -->) ensures subsequent deploys update the existing comment rather than creating new ones.
Required Permissions
The workflow needs pull-requests: write permission:
permissions:
contents: read
pull-requests: write