feat: add Google sign-up option to Console#3104
Conversation
Greptile SummaryThis PR adds "Sign in/up with Google" buttons to both the login and register pages, mirroring the existing GitHub OAuth pattern exactly (same URL-handling logic, same button structure, same
Confidence Score: 5/5Safe to merge — the Google OAuth handlers are faithful copies of the existing GitHub handlers with no new logic. Both new onGoogleLogin() functions mirror their onGithubLogin() counterparts exactly: same URL construction, same createOAuth2Session call structure, only the provider enum and OAuth scopes differ. No new redirect logic, no new state management, and no new API surface was introduced. No files require special attention beyond the known spacing inconsistency in the register page already flagged in prior review threads. Important Files Changed
Reviews (2): Last reviewed commit: "feat: add Google sign-in option to login..." | Re-trigger Greptile |
| </Button> | ||
| <div style:margin-top="var(--gap-s, 8px)"> | ||
| <Button secondary fullWidth on:click={onGoogleLogin} {disabled}> | ||
| <span class="icon-google" aria-hidden="true"></span> |
There was a problem hiding this comment.
icon-google class has no prior usage in the codebase
Every other OAuth icon (icon-github) appears in five files, but icon-google is introduced here for the first time. The icon CSS is loaded globally from @appwrite.io/pink-icons via +layout.ts. If this class is not defined in the currently-pinned version of that package (0.25.0), the button renders with no icon — a silently broken UI. Since node_modules are not committed and the package is sourced from a private registry, the class availability cannot be verified from the diff alone. Please confirm icon-google is exported by @appwrite.io/pink-icons@0.25.0 before merging.
There was a problem hiding this comment.
Confirmed — icon-google is exported by @appwrite.io/pink-icons@0.25.0. I verified it locally, and the icon renders correctly. Thanks for flagging this!
| function onGoogleLogin() { | ||
| let successUrl = window.location.origin; | ||
|
|
||
| if (page.url.searchParams.has('code')) { | ||
| successUrl += `?code=${page.url.searchParams.get('code')}`; | ||
| } else if (page.url.searchParams.has('campaign')) { | ||
| successUrl += `?campaign=${page.url.searchParams.get('campaign')}`; | ||
| } | ||
|
|
||
| sdk.forConsole.account.createOAuth2Session({ | ||
| provider: OAuthProvider.Google, | ||
| success: successUrl, | ||
| failure: window.location.origin, | ||
| scopes: ['profile', 'email'] | ||
| }); | ||
| } |
There was a problem hiding this comment.
Google OAuth is missing from the sign-in page
The login page (/login) only offers GitHub OAuth, so a user who registers with Google will find no matching sign-in option on the login page and will likely be confused or stranded. If the intent is to ship both pages together, the corresponding onGoogleLogin() handler and button need to be added to src/routes/(public)/(guest)/login/+page.svelte as well.
There was a problem hiding this comment.
Addressed — I’ve added the corresponding Google OAuth handler and button to the sign-in page as well, so users who register with Google can also sign in using the same provider. Thanks for catching this!
| <div style:margin-top="var(--gap-s, 8px)"> | ||
| <Button secondary fullWidth on:click={onGoogleLogin} {disabled}> | ||
| <span class="icon-google" aria-hidden="true"></span> | ||
| <span class="text">Sign up with Google</span> | ||
| </Button> | ||
| </div> |
There was a problem hiding this comment.
Spacing via nested div instead of
Layout.Stack
The PR description says "Wrapped both OAuth buttons in a Layout.Stack for consistent spacing," but the implementation uses a raw <div style:margin-top> instead. Layout.Stack is already imported and used on this page (wrapping the full form), so a gap-based stack would be cleaner and consistent with the design system's intent. A <div> with an inline style bypasses the design token system and adds nesting that isn't necessary.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
There was a problem hiding this comment.
Good catch — the PR description was outdated here. The current implementation uses a regular div with the spacing token rather than Layout.Stack. I’ll update the PR description to match the implementation. If Layout.Stack is preferred for consistency with the project’s design system, I’m happy to update the implementation as well.
There was a problem hiding this comment.
Thanks for the context! Looking at the actual code, the cleanest fix would be to wrap the two OAuth buttons in their own Layout.Stack with a gap, replacing both the outer <div style:margin-bottom> and the inner <div style:margin-top>:
| <div style:margin-top="var(--gap-s, 8px)"> | |
| <Button secondary fullWidth on:click={onGoogleLogin} {disabled}> | |
| <span class="icon-google" aria-hidden="true"></span> | |
| <span class="text">Sign up with Google</span> | |
| </Button> | |
| </div> | |
| <Layout.Stack gap="s"> | |
| <Button secondary fullWidth on:click={onGithubLogin} {disabled}> | |
| <span class="icon-github" aria-hidden="true"></span> | |
| <span class="text">Sign up with GitHub</span> | |
| </Button> | |
| <Button secondary fullWidth on:click={onGoogleLogin} {disabled}> | |
| <span class="icon-google" aria-hidden="true"></span> | |
| <span class="text">Sign up with Google</span> | |
| </Button> | |
| </Layout.Stack> |
This keeps spacing declarative via the design token system and avoids the extra nesting. Either way works — just a consistency preference.
Tip: You can customize Greptile's behavior for this repo with .greptile/rules.md and .greptile/config.json.
What this PR does
Adds a "Sign up with Google" option to the Console sign-up page, alongside the existing GitHub OAuth option.
Adds a "Sign in with Google" option to the Console sign-in page, alongside the existing GitHub OAuth option.
Changes
onGoogleLogin()handler using the existingOAuthProvider.Googleprovider from the SDKTesting
Tested locally against a self-hosted Appwrite instance with
PUBLIC_CONSOLE_MODE=cloudset temporarily to verify rendering. Both buttons render correctly and trigger their respective OAuth flows. Google OAuth provider wasn't configured in my local test project, so the full redirect wasn't exercised end-to-end, but the button correctly callscreateOAuth2Sessionwith the Google provider.Closes appwrite/appwrite#12777