Skip to content

fix(invite): add /invite where cloudflare pages reads it - #1895

Merged
LucasSantana-Dev merged 1 commit into
mainfrom
fix/invite-cf-pages-redirect
Jul 27, 2026
Merged

LucasSantana-Dev merged 1 commit into
mainfrom
fix/invite-cf-pages-redirect

Conversation

@LucasSantana-Dev

@LucasSantana-Dev LucasSantana-Dev commented Jul 27, 2026 •

Copy link
Copy Markdown
Owner

Third attempt at #1888, and the first one aimed at the layer that actually serves the site. Correcting myself: the previous two fixes were in the wrong place.

Where the traffic really goes

host served by governed by
lucky.lucassantana.tech Cloudflare Pages (lucky-webapp, deploy-frontend-cf.yml) packages/frontend/public/_redirects
lucky-api.lucassantana.tech Cloudflare Tunnel → homelab nginx nginx/nginx.conf

So vercel.json (#1889) applies to neither, and the nginx block (#1893) applies only to the API host. The public site kept returning 200 with the SPA.

How I confirmed it rather than guessing again

The live response for /invite carries:

content-security-policy: ... script-src 'self' https://static.cloudflareinsights.com ...

That static.cloudflareinsights.com allowance exists only in packages/frontend/public/_headers. nginx/nginx.conf serves a different CSP without it, so the request was demonstrably never reaching nginx.

Meanwhile the API host already works, which confirms #1893 landed correctly:

$ curl -sI https://lucky-api.lucassantana.tech/invite
HTTP/2 302
location: https://discord.com/oauth2/authorize?client_id=962198089161134131&scope=bot%20applications.commands&permissions=3165184

The change

_redirects rules are evaluated top to bottom, and the existing /* /index.html 200 catch-all matched /invite first — that is the mechanism that swallowed every invite click.

/invite  https://lucky-api.lucassantana.tech/invite  302
/*       /index.html                                 200

Points at the backend rather than Discord directly, so the [invite] click utm logging from #1893 still runs.

Nothing from #1893 is reverted: the nginx block and the shared BOT_INVITE_PERMISSIONS constant are what make the destination correct.

Verification

_redirects confirmed present in packages/frontend/dist/ after npm run build:frontend, which is the directory wrangler pages deploy uploads.

Will verify against production once the Pages deploy runs.


Summary by cubic

Adds a Cloudflare Pages _redirects rule so /invite now 302s to the backend, fixing the route being swallowed by the SPA. Keeps UTM tracking by routing through the API.

Written for commit fbb7674. Summary will update on new commits.

Review in cubic

I fixed this twice in the wrong layer. lucky.lucassantana.tech is served
by Cloudflare Pages (project lucky-webapp, deploy-frontend-cf.yml), not
by Vercel and not by the homelab nginx behind the tunnel. So neither the
vercel.json redirect (#1889) nor the nginx location block (#1893) applied
to the public site, and /invite kept returning 200 with the SPA.

What gave it away: the live response carries a CSP allowing
static.cloudflareinsights.com, which appears only in
packages/frontend/public/_headers. The nginx config serves a different
CSP, so the request was never reaching it.

Meanwhile lucky-api.lucassantana.tech DOES go through the tunnel, and
already returns the correct 302 with permissions=3165184, so the backend
handler and the nginx work from #1893 are both fine and stay.

_redirects rules are evaluated top to bottom, so /invite is placed above
the SPA catch-all, which is what was swallowing it. Points at the backend
rather than Discord directly so the utm_* attribution logging still runs.

Verified the file lands in packages/frontend/dist after a build, which is
the directory `wrangler pages deploy` uploads.
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@LucasSantana-Dev, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 1 minute

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 4e16eff5-10d5-4fa9-bda2-3c025810b712

📥 Commits

Reviewing files that changed from the base of the PR and between 6cf7358 and fbb7674.

📒 Files selected for processing (1)
  • packages/frontend/public/_redirects
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/invite-cf-pages-redirect

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

Failed to generate code suggestions for PR

@github-actions

Copy link
Copy Markdown

Size Change: 0 B

Total Size: 498 kB

ℹ️ View Unchanged
Filename Size
packages/frontend/dist/assets/AddStyledRoleForm-D5fY9xk1.js 3.11 kB
packages/frontend/dist/assets/Admin-DhJ1zlfC.js 2.3 kB
packages/frontend/dist/assets/AdminSupport-D3h_aanv.js 1.6 kB
packages/frontend/dist/assets/api-BBv75RPO.js 3.76 kB
packages/frontend/dist/assets/AutoMessages-C1Md_m1m.js 2.65 kB
packages/frontend/dist/assets/AutoMod-xsWHjhV-.js 4.19 kB
packages/frontend/dist/assets/badge-C6YVNcb-.js 501 B
packages/frontend/dist/assets/BatchJobs-CmFyEW2H.js 3.72 kB
packages/frontend/dist/assets/Card-DMiKSa7r.js 506 B
packages/frontend/dist/assets/Changelog-xuZpJ8R_.js 59.4 kB
packages/frontend/dist/assets/CommandsConfig-CdEixqJk.js 1.5 kB
packages/frontend/dist/assets/Config-BcskRNcn.js 1.93 kB
packages/frontend/dist/assets/constants-DfwHQtAY.js 605 B
packages/frontend/dist/assets/CustomCommands-BTiwG3ZX.js 2.12 kB
packages/frontend/dist/assets/DashboardOverview-BhE7dA4e.js 3.95 kB
packages/frontend/dist/assets/dialog-5nay2gJX.js 958 B
packages/frontend/dist/assets/Docs-OaXXBHai.js 17.5 kB
packages/frontend/dist/assets/DocsShell-s-GWPiaD.js 1.42 kB
packages/frontend/dist/assets/EmbedBuilder-CLV5_kSk.js 3.28 kB
packages/frontend/dist/assets/Features-Z8B291zl.js 757 B
packages/frontend/dist/assets/GuildAutomation-BbD6qTJ2.js 2.89 kB
packages/frontend/dist/assets/index-CHFc-BYo.js 71.2 kB
packages/frontend/dist/assets/index-DY6JagVQ.css 17.6 kB
packages/frontend/dist/assets/input-rutFY47j.js 463 B
packages/frontend/dist/assets/label-lpvI1wg2.js 476 B
packages/frontend/dist/assets/Landing-DImzEg5r.js 5.11 kB
packages/frontend/dist/assets/LastFm-DbDn8MOV.js 1.74 kB
packages/frontend/dist/assets/legalNav-B6k3CWsW.js 274 B
packages/frontend/dist/assets/Levels-jMh62qPU.js 2.27 kB
packages/frontend/dist/assets/Login-pALKyxkr.js 2.49 kB
packages/frontend/dist/assets/Lyrics-BoeqWhGJ.js 1.34 kB
packages/frontend/dist/assets/Moderation-D83UJVUv.js 3.78 kB
packages/frontend/dist/assets/Music-W4J_sRCy.js 5.96 kB
packages/frontend/dist/assets/MusicConfig-mW4zrHXz.js 1.68 kB
packages/frontend/dist/assets/PreferredArtists-SF8TUfdn.js 3.72 kB
packages/frontend/dist/assets/PrivacyPolicy-EQH7xMCJ.js 1.77 kB
packages/frontend/dist/assets/ReactionRoles-DgT3PBmR.js 7.04 kB
packages/frontend/dist/assets/RoleGroups-BFQ9OOF9.js 2.24 kB
packages/frontend/dist/assets/Roles-l-EGEjVK.js 3.34 kB
packages/frontend/dist/assets/rolldown-runtime-Cyuzqnbw.js 471 B
packages/frontend/dist/assets/routeMeta-BZjtwMbs.js 595 B
packages/frontend/dist/assets/SectionHeader-BPzT6yW4.js 895 B
packages/frontend/dist/assets/select-DpqvPUNQ.js 1.23 kB
packages/frontend/dist/assets/sentry-DhXOA89y.js 3.76 kB
packages/frontend/dist/assets/ServerLogs-D2NJyJoF.js 3.04 kB
packages/frontend/dist/assets/ServerSettings-ZRspNlsN.js 3.98 kB
packages/frontend/dist/assets/ServersPage-BmFmTTUm.js 3.03 kB
packages/frontend/dist/assets/Skeleton-D125h-OM.js 237 B
packages/frontend/dist/assets/Spotify-nbeE_i2G.js 1.75 kB
packages/frontend/dist/assets/Starboard-DB1h2IW5.js 1.82 kB
packages/frontend/dist/assets/StatTile-B9ZKD19V.js 640 B
packages/frontend/dist/assets/Support-5EMZQKv_.js 1.56 kB
packages/frontend/dist/assets/switch-B9m-fn8D.js 541 B
packages/frontend/dist/assets/TermsOfService-Dkv1_FLz.js 1.59 kB
packages/frontend/dist/assets/TrackHistory-CdMpCPMz.js 2.31 kB
packages/frontend/dist/assets/TwitchNotifications-BWDStbP3.js 2.44 kB
packages/frontend/dist/assets/useActiveHeading-DEWtNcoa.js 1.35 kB
packages/frontend/dist/assets/useFeatures-DB6gK7uI.js 2.06 kB
packages/frontend/dist/assets/usePageMetadata-DTv-6eVb.js 327 B
packages/frontend/dist/assets/vendor-forms-C-bof8GF.js 25.9 kB
packages/frontend/dist/assets/vendor-radix-qkfmDH9H.js 39.9 kB
packages/frontend/dist/assets/vendor-react-B7C34xnu.js 55.7 kB
packages/frontend/dist/assets/vendor-state-Kvbn3gqw.js 25.2 kB
packages/frontend/dist/assets/vendor-ui-BBN61NBD.js 66.2 kB

compressed-size-action

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 1 file

Auto-approved: Adds a single redirect rule to fix the /invite route being swallowed by the SPA catch-all. The change is bounded (one route, one rule) and clearly beneficial as a focused bug fix.

Re-trigger cubic

@sonarqubecloud

Copy link
Copy Markdown

@LucasSantana-Dev
LucasSantana-Dev merged commit 0528f66 into main Jul 27, 2026
45 checks passed
@LucasSantana-Dev
LucasSantana-Dev deleted the fix/invite-cf-pages-redirect branch July 27, 2026 14:00
LucasSantana-Dev added a commit that referenced this pull request Jul 27, 2026
🤖 I have created a release *beep* *boop*
---


<details><summary>2.38.0</summary>

##
[2.38.0](v2.37.3...v2.38.0)
(2026-07-27)


### Features

* **bot:** add /ticket-setup for support category and agent role
([#1863](#1863))
([3f4af39](3f4af39))
* **frontend:** per-action loading and connection gating on music
controls
([#1866](#1866))
([2dda60f](2dda60f))
* **frontend:** show stale progress when music SSE lags
([#1867](#1867))
([4952e73](4952e73))
* **music:** surface recommendationReason in nowplaying and queue
([#1864](#1864))
([960fd62](960fd62))
* **ops:** blue/green zero-downtime deploys — Phase 1 web tier
([#1786](#1786))
([f5f7597](f5f7597))


### Bug Fixes

* **docker:** make compose stack boot from a fresh .env
([#1674](#1674))
([babe0ef](babe0ef))
* **docker:** treat an empty db password as missing in compose guards
([#1881](#1881))
([718c0ad](718c0ad))
* **frontend:** make landing page usable at mobile widths
([#1865](#1865))
([6190350](6190350))
* **frontend:** stop hero grid columns overflowing on narrow viewports
([#1874](#1874))
([ce5cea0](ce5cea0))
* **invite:** add /invite where cloudflare pages reads it
([#1895](#1895))
([0528f66](0528f66))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
LucasSantana-Dev added a commit that referenced this pull request Sep 8, 2026
## Summary
Nothing in the repo said which of the three independent hosting layers
(Cloudflare Pages, Cloudflare Tunnel + homelab nginx, legacy Vercel
preview) serves which host, or which config file governs each. Fixing
the /invite redirect took three PRs (#1889, #1893, #1895) before landing
in the right file.

- Added a "Deployment & hosting" section to docs/ARCHITECTURE.md: the
host/layer/config table, the CSP trick for identifying which layer
answered a request, and the nginx.conf/_redirects gotchas that cost time
before.
- Added a one-line pointer to that section at the top of nginx.conf and
_redirects.
- vercel.json and _headers intentionally left untouched: vercel.json is
strict JSON with no safe comment syntax, and _headers' Cloudflare Pages
comment support isn't proven in this repo the way _redirects' is (its
existing comment block already works in production - _headers has none
to point to as precedent). Not worth guessing on a live config file for
a one-line pointer when docs/ARCHITECTURE.md already names both files.

## Test plan
- [x] Read-only doc/comment change, no code paths touched
- [x] nginx.conf comment uses `#`, the format nginx already uses
throughout this file
- [x] _redirects comment extends the file's own pre-existing `#` comment
block, proven safe since it's already live in production

Closes #1924

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Documents which of the three hosting layers (Cloudflare Pages,
Cloudflare Tunnel + homelab nginx, legacy Vercel preview) serves which
host and which config file governs each, so fixes like `/invite` land in
the right file instead of taking three PRs.

- Adds a Deployment & hosting section to `docs/ARCHITECTURE.md` with the
host/layer/config table, the CSP trick for identifying which layer
answered, the `nginx.conf` `/api`-proxying rule plus its `/invite`,
`/webhook/`, `/webhooks/` exceptions, and the `_redirects` top-to-bottom
gotcha.
- Adds pointers to that section at the top of `nginx.conf` and
`_redirects`.
- Read-only change; leaves `vercel.json` and `_headers` untouched.
Closes #1924.

<sup>Written for commit 4b401a0.
Summary will update on new commits.</sup>

<a
href="https://cubic.dev/pr/LucasSantana-Dev/Lucky/pull/2253?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->
This was referenced Oct 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant