GitHub integration is optional but unlocks production shipping. Studio works end-to-end without GitHub - scaffold from a framework template, build with the chat, iterate against the live preview, and share via the preview URL or a workspace download. Connect GitHub when you’re ready to push work to a real repo, open pull requests, and run it through your team’s review flow.Once connected, Studio builds on real Git branches in real repositories. File changes the Studio chat makes are committed to a branch on your GitHub repository, and you open a pull request through GitHub’s normal flow. No custom review tool, no “AI commits” marker - ordinary Git that happens to have been authored through a chat interface.This page covers the full GitHub-side flow: installing the Frontic GitHub App, committing from the Changes panel, opening a PR, and coordinating PRs with Releases when a change touches both frontend code and stack config.
GitHub integration uses a GitHub App installed on your GitHub organization (or personal account). It’s an organization-wide install: a GitHub admin sets it up once, and every teammate on the Frontic project can use Git features in Studio - push, branch, open PRs - with no individual GitHub setup of their own.You can start the install from either of two places:
From Studio Settings
Open Studio Settings (the gear icon in the Board header), open the GitHub section, and click
Install GitHub App. Useful when you want to set up GitHub up front,
before any job.
From a Create Job dialog
Open Create Job, expand Source configuration, and switch the source to GitHub Repository. Install the GitHub App inline; the dialog returns with repository mode pre-configured, ready to pick the repo and branch.
Either path opens GitHub’s App installation flow, where you pick the organization to install on and choose which repositories the App can access. After you confirm, the installation is saved at the project level and every subsequent job can target any repository you granted access to. You can connect additional GitHub organizations at any time - each gets its own installation, and all active installations are listed in Studio Settings → GitHub.
Installing on an organization may require approval from a GitHub org admin if your organization restricts third-party App installs. If you don’t see your org in the picker, ask an admin to install the Frontic GitHub App for you. This approval applies per organization - when you add a second or third org, a GitHub admin for that org needs to approve it too.
Once the App is installed, Create Job uses your connection to pre-fill the source. The dialog opens with Source configuration collapsed - its summary line shows the current selection (a template name when no GitHub is connected, or the repository’s full name when one is). When you’ve used a repository before, that one comes back pre-selected, and the base branch field is pre-filled with the last branch you targeted. With a fresh install and a single accessible repo, that repo is picked silently. Multiple accessible repos with no history is the only case that opens with the section expanded so you can choose.
Create Job dialog with Source configuration expanded, GitHub Repository selected, the chosen repo, and the base branch selector
After the App is installed, each connected organization shows its own Repository Access panel in Studio Settings listing the repositories Studio can see for that org. The list is paginated - load more if you have many repos. If you have multiple organizations connected, each appears as its own installation card with its own Repository Access panel.To change which repositories the App can access for an org, click Manage Repositories on that org’s installation card. That redirects you to the GitHub App’s installation settings on GitHub, where you can add or remove repositories. Save there, and GitHub redirects you back to Studio with the new list. Changes apply immediately for everyone on the project.Use this when:
A new repository was created after the App was installed and isn’t in the picker yet
You want to scope Studio to a narrower set of repos than what’s currently granted
The Studio chat creates a new branch off the base branch you pick
Every file edit is a change on that branch
Clicking Commit in the Changes panel commits on the branch and pushes to GitHub in one step
Pull requests target the base branch
Everything is standard Git. Commits are authored by the GitHub App, not by the teammate who ran the job - so don’t use the commit author field for attribution.
Each Studio job picks its own repository and base branch at creation - there’s no per-project default repository to override. If your team maintains multiple frontends (web storefront, mobile app, admin surface) against the same Frontic project, each can live in its own repo - including repos across different GitHub organizations if you have multiple orgs connected - and jobs target whichever one you’re working on.
From Frontic - Go to Studio Settings → GitHub and click Uninstall & Disconnect on the installation you want to remove. Each connected organization is disconnected independently - removing one does not affect other connected organizations. Existing jobs that target that org’s repositories finish; no new jobs can be created against those repositories until the App is reinstalled.
From GitHub - in your organization’s Settings → GitHub Apps → Frontic Studio, click Uninstall. GitHub enforces immediately.
Neither deletes already-committed work - that’s in your Git history and belongs to you.
Not every job starts from GitHub. When you scaffold a job from a framework template (Nuxt or Next.js), the workspace has no repository connected. Create Repository enables you to create a new GitHub repository from a template job in one step.The action only appears while the job has no repository connected. You’ll find it in two places: the workspace panel toolbar, and the Changes panel, which shows it in place of the file list until a repository exists. Both open the same dialog.
GitHub connected at the project level - the Frontic GitHub App is installed (see Connecting GitHub).
At least one organization installation - the org picker lists GitHub organizations only. Personal GitHub accounts aren’t supported here. If your only installation is a personal account, connect an organization from Studio Settings → GitHub first.
The dialog handles the gaps for you. If GitHub isn’t connected at all, it shows an inline Connect GitHub prompt - the same install flow as Studio Settings or Create Job. If GitHub is connected but no organization is available, it links you to Studio Settings → GitHub to add one.
Click Create Repository in the workspace panel toolbar or in the
Changes panel.
Pick the organization
Choose the GitHub organization to create the repository under. When
only one organization is connected, it’s pre-selected.
Name the repository
Enter a name - letters, numbers, hyphens, underscores, and dots, 1–100
characters. Add an optional description if you like.
Choose visibility
The repository is private by default. Flip the toggle to make it
public.
Confirm
Studio creates the repository under the organization, pushes the
current workspace as the initial commit, and connects it to the job.
Once it’s done, the job is a normal GitHub-backed job: the Changes panel is live, and the full Commit → push → open a pull request flow works exactly as it does for a job that started from an existing repository.
The repository is created empty and your current workspace lands as the first commit on the default branch (main). There’s no separate base branch to choose - this flow both creates the repo and pushes to it in one confirm.
Once Studio has made file changes you’re happy with, commit them from the workspace. The Workspace page covers reviewing the diffs in detail; this section covers the commit mechanics.
Review the diffs
Before committing, open the Changes panel and read every file - not
only the ones you expected. Agents sometimes touch imports, shared
utilities, or generated files you didn’t mention. Worth knowing
what landed.
Review or write a commit message
Studio drafts a commit message from the diff as soon as the dialog
opens. If you want to write your own commit message, just start
typing - your text is kept and the suggestion is dropped.
Confirm the target branch
The dialog has a Commit changes to row that shows the branch
the commit will land on - the workspace’s feature branch by default.
Click the row to expand it and switch to a different existing branch
or create a new one (under the hood it’s the standard branch
selector with Existing branch and Create new branch
options). Leave it collapsed when the default is right.
Click Commit
Studio commits on the branch and pushes to GitHub in one step. The
first commit creates the branch on GitHub; later commits fast-forward
it. The Changes panel shows the branch up to date with remote when
it’s done.
When a commit moves the job onto a new branch - usually your first commit to the feature branch - the success notification offers Create Pull Request. It opens GitHub’s compare page from the branch the job was on to the one you just committed to, with the pull request already drafted:
Title - the first line of your commit message.
Description - a short changelog Studio writes from the job’s conversation and the committed changes: what changed and what it enables, in plain language, without file names or Git jargon.
Both land in GitHub’s own form, so edit or replace them, add the context your team needs (ticket links, screenshots, test notes), and create the PR as you normally would. If the description can’t be written within a few seconds, the page opens with only the title filled in and you write the description yourself. Later commits to the same branch don’t offer the action again; open the PR from GitHub if you skipped it.
Spend 30 seconds on the drafted description before you create the PR. It says what changed; add why it changed and what to look at first. A good description saves more review time than it takes to write.
When the PR is approved and CI is green, merge it like any other PR. After merge:
The feature branch can be deleted (your team’s usual branch cleanup applies)
The Studio job stays around - you can reopen it later for follow-up work in the same workspace
If the change involved stack configuration (new blocks, listings, pages) that went through a preview release, promote the preview if you haven’t already
A PR is about code. A release is about stack config. When a change involves both - which most meaningful changes do - the order matters:
Preview the stack change first
Create a preview in the admin app so the stack state is frozen.
Generate the Client SDK against the preview
Run frontic generate --env preview (or frontic generate and pick
preview from the prompt). The SDK embeds a version token pointing
at the preview.
Commit the SDK + frontend code
Commit the generated client files alongside the frontend code that
uses them. Push the branch.
Open the PR
Mention in the description that there’s an accompanying preview
release and link to it. Reviewers need to know the PR depends on
stack state that isn’t public yet.
Deploy the PR to a preview environment
Your deploy pipeline builds a preview deploy. Because the SDK in
the branch carries the preview token, the preview deploy talks to
the Frontic preview - so QA validates the full stack, not only
the code.
Merge the PR
Production deploys the new frontend. Because the SDK carries the
preview token, production is now talking to the Frontic preview -
so real traffic hits the validated stack state.
Promote the Frontic preview
Promote the preview to public. The preview version becomes the
new public; the token your frontend is pinned to falls back to
public gracefully - same content, no code change needed.
The preview-then-promote sequence gives you a QA checkpoint where the frontend and stack state are both frozen, so you’re not chasing a moving target. For a worked example, see Your First Feature.
Preview - the next iteration of this flow pairs a draft with the Studio job and the PR, so the stack sandbox, the frontend code, and the release that ships both move together. In preview today; expanding as it matures.
The repository wasn’t included in the App’s repository access grant.
In Studio Settings → GitHub, click Manage Repositories to
open the GitHub App’s installation settings, add the missing repo,
and save. The picker refreshes with the new list.
The GitHub App installation didn't complete
Most often this is an organization permissions issue: the org
requires admin approval for third-party App installs, and the
request is still pending. Ask a GitHub org admin to approve (or
install) the Frontic Studio App for the organization. If you
cancelled the install partway through, just click Install GitHub
App again.
A teammate can't push to GitHub from Studio
Once the App is installed on the org, every teammate on the Frontic
project gets Git access - no per-user GitHub setup is required. If
a teammate is blocked, check that the repository they’re working on
is included in the App’s repository access (see Manage
Repositories) and that they have the Frontic permissions to use
Studio in this project.
Connecting a GitHub organization that's already connected to another Frontic team
Supported. From the second Frontic team, go to Studio Settings → GitHub
and click Install GitHub App, then complete
the GitHub App authorization flow. When GitHub redirects back,
Frontic detects that the same installation is being attached to a
new Frontic team and finalises the connection. Both Frontic
teams can then target repositories under the same GitHub
organization independently - each has its own repository access
settings and its own job and workspace history.Note: this is distinct from connecting multiple GitHub organizations to a single Frontic project - use the Add GitHub Organization button in Studio Settings → GitHub for that.
Create Repository fails saying the App can't create repositories in this organization
The Frontic GitHub App installation for that organization doesn’t have
permission to create repositories. Reconfigure the installation to
grant repository administration access - in Studio Settings →
GitHub, use Manage Repositories on that org’s card to open its
GitHub App settings, then approve the added permission (a GitHub org
admin may need to do this). Once granted, reopen the dialog and try
again.
I connected a second GitHub org but its repositories aren't showing in the picker
The GitHub App installation for that org may not include the repositories you need. In Studio Settings → GitHub, find the installation card for the org you just added and click Manage Repositories. This opens the GitHub App’s installation settings for that org, where you can add the missing repositories and save. The picker refreshes immediately.
How the stack-side of your changes moves between stages. (Plus plan.)
Studio
Where chat-driven changes happen before they hit the connected
repository.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Frontic Docs","description":"Frontic - an AI platform for shipping shopping experiences in a fraction of the time, with double the fun.","colors":{"primary":"#a855f7","light":"#c084fc","dark":"#8b5cf6"},"logo":{"light":"https://mintcdn.com/frontic/QEEg-J3fIyHJ_Wyh/logo/logo-light.svg?fit=max\u0026auto=format\u0026n=QEEg-J3fIyHJ_Wyh\u0026q=85\u0026s=36391b9f3546193a73f97d7b6ee40463","dark":"https://mintcdn.com/frontic/QEEg-J3fIyHJ_Wyh/logo/logo-dark.svg?fit=max\u0026auto=format\u0026n=QEEg-J3fIyHJ_Wyh\u0026q=85\u0026s=704f0d073af32f152eab7ab9e4229a9b"},"favicon":"https://mintcdn.com/frontic/QEEg-J3fIyHJ_Wyh/logo/light.svg?fit=max\u0026auto=format\u0026n=QEEg-J3fIyHJ_Wyh\u0026q=85\u0026s=add2ba40542c32e89fccea55bbd2afbd","api":{"playground":{"display":"interactive"},"mdx":{"auth":{"method":"key","name":"Authorization"},"server":"https://ingest-{integration-id}.frontic.com"}},"appearance":{"default":"dark","strict":false},"navbar":{"links":[{"href":"mailto:support@frontic.com","label":"Support"},{"href":"https://www.frontic.com","label":"Website"}],"primary":{"type":"button","label":"Log In","href":"https://app.frontic.com"}},"footer":{"socials":{"github":"https://github.com/frontic","linkedin":"https://www.linkedin.com/company/102853312"},"links":[{"header":"Resources","items":[{"label":"Changelog","href":"https://frontic.com/changelog"},{"label":"Status","href":"https://status.frontic.com"}]},{"header":"Company","items":[{"label":"Website","href":"https://www.frontic.com"},{"label":"Support","href":"mailto:support@frontic.com"}]}]},"search":{"prompt":"Search Frontic docs..."},"styling":{"codeblocks":{"theme":"css-variables"},"latex":false},"integrations":{"posthog":{"apiKey":"phc_4DuVaMwZYdzCq7HW2hyorMIALyLvxWvC2STOIk8z1lr","apiHost":"https://eu.posthog.com"}},"contextual":{"options":["copy","chatgpt","claude","mcp","cursor"],"display":"header"},"navigation":{"global":{},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"frontic","hasAudioNarration":false,"actualSubdomain":"frontic","customDomains":["docs.frontic.com"],"gitSource":{"type":"github","owner":"frontic","repo":"docs","deployBranch":"main","isPrivate":true,"contentDirectory":"","mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ae7c42deeb506b36f78cabb","collectionId":"1bbaa1b1-930b-4c2d-b260-45171d33ed14","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ae7c42deeb506b36f78cabb"},"feedback":{"agentFeedback":true},"entitlements":{},"buildId":"6ae7c42deeb506b36f78cabb","clientVersion":"0.0.4045","searchFilterCounts":[{"language":"default","tag":"Documentation","count":52},{"language":"default","tag":"Connectors","count":24},{"language":"default","tag":"Reference","count":24},{"language":"default","tag":"Fetch API","count":9},{"language":"default","tag":"Build in Frontic","count":8},{"language":"default","tag":"Context Base","count":7},{"language":"default","tag":"Essentials","count":7},{"language":"default","tag":"Project Settings","count":7},{"language":"default","tag":"Ingest API","count":6},{"language":"default","tag":"API Builder","count":5}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":"@keyframes glow-float-1{0%,to{transform:translate(0,0) scale(1)}50%{transform:translate(30px,20px) scale(1.1)}}@keyframes glow-float-2{0%,to{transform:translate(0,0) scale(1)}50%{transform:translate(-20px,30px) scale(1.15)}}@keyframes glow-float-3{0%,to{transform:translate(0,0) scale(1)}50%{transform:translate(20px,-20px) scale(1.05)}}:root{--frontic-purple:#a042ff;--frontic-purple-secondary:#784dcb;--frontic-purple-light:#c084fc;--frontic-violet:#8b5cf6;--frontic-dark-bg:#131117}html.dark{background:#0a0a0f}html.dark body{background:0 0}html.dark body::after,html.dark body::before,html.dark::before{content:\"\";position:fixed;border-radius:50%;filter:blur(112px);opacity:.5;pointer-events:none;z-index:-1}html.dark body::before{top:-10%;left:10%;width:600px;height:600px;background:radial-gradient(circle,rgba(160,66,255,.4) 0,transparent 70%);animation:glow-float-1 8s ease-in-out infinite}html.dark body::after{top:30%;right:5%;width:500px;height:500px;background:radial-gradient(circle,rgba(120,77,203,.35) 0,transparent 70%);animation:glow-float-2 10s ease-in-out infinite}html.dark::before{bottom:10%;left:30%;width:400px;height:400px;background:radial-gradient(circle,rgba(168,85,247,.25) 0,transparent 70%);animation:glow-float-3 9s ease-in-out infinite}html:not(.dark){background:#fafafa;--mint-background:#faf5ff;--mint-foreground:#111827;--mint-color-text:#111827;--mint-color-background:#faf5ff;--mint-token-constant:#7c3aed;--mint-token-string:#059669;--mint-token-comment:#9ca3af;--mint-token-keyword:#a855f7;--mint-token-parameter:#6366f1;--mint-token-function:#8b5cf6;--mint-token-string-expression:#059669;--mint-token-punctuation:#6b7280;--mint-token-link:#a855f7}html:not(.dark) body{background:0 0}html:not(.dark) body::after,html:not(.dark) body::before{content:\"\";position:fixed;border-radius:50%;filter:blur(100px);pointer-events:none;z-index:-1}html:not(.dark) body::before{top:-10%;left:10%;width:600px;height:600px;background:radial-gradient(circle,rgba(160,66,255,.15) 0,transparent 70%);animation:glow-float-1 8s ease-in-out infinite}html:not(.dark) body::after{top:40%;right:5%;width:500px;height:500px;background:radial-gradient(circle,rgba(120,77,203,.12) 0,transparent 70%);animation:glow-float-2 10s ease-in-out infinite}.prose,[class*=content],body,main,nav:not([class*=top]){background:0 0!important}html.dark #sidebar{background:linear-gradient(180deg,rgba(160,66,255,.03) 0,transparent 100%)!important}#sidebar,#sidebar-content{box-shadow:none!important}html.dark header,html.dark nav{border-bottom-color:rgba(160,66,255,.1)!important}html.dark .code-group{border-top:1px solid rgba(160,66,255,.15)!important;border-radius:8px!important}html:not(.dark) .code-group{border:1px solid rgba(160,66,255,.1)!important;border-radius:8px!important;background-color:#faf5ff!important;color:#111827!important}pre{border:0!important}html.dark{--mint-background:#1a1625;--mint-foreground:#e5e7eb;--mint-color-text:#e5e7eb;--mint-color-background:#1a1625;--mint-token-constant:#c4b5fd;--mint-token-string:#6ee7b7;--mint-token-comment:#6b7280;--mint-token-keyword:#c084fc;--mint-token-parameter:#a5b4fc;--mint-token-function:#a78bfa;--mint-token-string-expression:#6ee7b7;--mint-token-punctuation:#9ca3af;--mint-token-link:#c084fc}html:not(.dark) :not(pre)>code{background-color:rgba(160,66,255,.08)!important;color:#6b21a8!important}html:not(.dark) .code-group [role=tab][aria-selected=true],html:not(.dark) .codeblock-dark [role=tab][aria-selected=true],html:not(.dark) button[aria-label*=opy] svg{color:#7c3aed!important}html:not(.dark) .code-group [role=tab]{color:#6b7280!important}html:not(.dark) .code-group [role=tab]:hover>div:first-child{background-color:rgba(160,66,255,.1)!important;color:#7c3aed!important}html:not(.dark) .code-group [role=tab][aria-selected=true]>div:last-child{background-color:#7c3aed!important}html:not(.dark) .codeblock-dark,html:not(.dark) .codeblock-dark [data-component-part=code-block-root]{background-color:#faf5ff!important;color:#111827!important}html:not(.dark) .codeblock-dark [data-fade-overlay=true]{--fade-color-light:#faf5ff!important;--fade-color-dark:#faf5ff!important}[role=listbox],[role=menu],[role=tooltip]{background-color:#fff!important;color:#1f2937!important;border:1px solid rgba(160,66,255,.15);border-radius:8px;box-shadow:0 12px 28px -8px rgba(0,0,0,.18);backdrop-filter:blur(8px)}html.dark [role=listbox],html.dark [role=menu],html.dark [role=tooltip]{background-color:#1a1625!important;color:#e5e7eb!important;border-color:rgba(160,66,255,.25);box-shadow:0 12px 28px -8px rgba(0,0,0,.6)}[role=tooltip] *{color:inherit!important}[class*=navbar]::after,[class*=sidebar]::after,[class*=sidebar]::before,[class*=topbar]::after,header::after,nav[class*=side]::after,nav[class*=side]::before,nav[class*=top]::after{background:0 0!important;background-image:none!important;background-color:transparent!important;display:none!important}[class*=sidebar]>div:first-child{background:0 0!important;background-color:transparent!important;background-image:none!important}#sidebar-content .sticky.top-0{background:0 0!important;background-image:none!important;background-color:transparent!important}[data-nav-tag=Preview]{color:#2563eb!important;background-color:rgba(37,99,235,.1)!important}html.dark [data-nav-tag=Preview]{color:#60a5fa!important;background-color:rgba(96,165,250,.15)!important}[data-nav-tag=New]{color:#16a34a!important;background-color:rgba(22,163,74,.1)!important}html.dark [data-nav-tag=New]{color:#4ade80!important;background-color:rgba(74,222,128,.15)!important}"}],"page":{"pagePath":"studio/github-integration","slug":"/studio/github-integration","pageMetadata":{"title":"GitHub Integration","icon":"github","description":null,"href":"/studio/github-integration"},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,em:`em`,li:`li`,p:`p`,strong:`strong`,ul:`ul`,..._provideComponents(),...props.components},{Accordion,AccordionGroup,Card,CardGroup,Frame,Heading,Info,OptimizedImage,Step,Steps,Tip}=_components;if(!Accordion)_missingMdxReference(`Accordion`,true);if(!AccordionGroup)_missingMdxReference(`AccordionGroup`,true);if(!Card)_missingMdxReference(`Card`,true);if(!CardGroup)_missingMdxReference(`CardGroup`,true);if(!Frame)_missingMdxReference(`Frame`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Info)_missingMdxReference(`Info`,true);if(!OptimizedImage)_missingMdxReference(`OptimizedImage`,true);if(!Step)_missingMdxReference(`Step`,true);if(!Steps)_missingMdxReference(`Steps`,true);if(!Tip)_missingMdxReference(`Tip`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`GitHub integration is `,_jsx(_components.strong,{children:`optional but unlocks production shipping`}),`. `,_jsx(_components.a,{href:`/studio/frontic-studio`,children:`Studio`}),` works end-to-end without GitHub - scaffold from a framework template, build with the chat, iterate against the live preview, and share via the preview URL or a workspace download. Connect GitHub when you’re ready to push work to a real repo, open pull requests, and run it through your team’s review flow.`]}),`\n`,_jsxs(_components.p,{children:[`Once connected, Studio builds on `,_jsx(_components.strong,{children:`real Git branches in real repositories`}),`. File changes the Studio chat makes are committed to a branch on your GitHub repository, and you open a pull request through GitHub’s normal flow. No custom review tool, no “AI commits” marker - ordinary Git that happens to have been authored through a chat interface.`]}),`\n`,_jsxs(_components.p,{children:[`This page covers the full GitHub-side flow: installing the Frontic GitHub App, committing from the Changes panel, opening a PR, and coordinating PRs with `,_jsx(_components.a,{href:`/releases/overview`,children:`Releases`}),` when a change touches both frontend code and stack config.`]}),`\n`,_jsx(Heading,{level:`2`,id:`connecting-github`,children:`Connecting GitHub`}),`\n`,_jsxs(_components.p,{children:[`GitHub integration uses a `,_jsx(_components.strong,{children:`GitHub App installed on your GitHub organization`}),` (or personal account). It’s an organization-wide install: a GitHub admin sets it up once, and every teammate on the Frontic project can use Git features in Studio - push, branch, open PRs - with no individual GitHub setup of their own.`]}),`\n`,_jsx(_components.p,{children:`You can start the install from either of two places:`}),`\n`,_jsxs(CardGroup,{cols:2,children:[_jsx(Card,{title:`From Studio Settings`,icon:`gear`,children:_jsxs(_components.p,{children:[`Open `,_jsx(_components.a,{href:`/studio/settings`,children:`Studio Settings`}),` (the gear icon in the Board header), open the GitHub section, and click\n`,_jsx(_components.strong,{children:`Install GitHub App`}),`. Useful when you want to set up GitHub up front,\nbefore any job.`]})}),_jsx(Card,{title:`From a Create Job dialog`,icon:`plus`,children:_jsxs(_components.p,{children:[`Open Create Job, expand `,_jsx(_components.strong,{children:`Source configuration`}),`, and switch the source to `,_jsx(_components.strong,{children:`GitHub Repository`}),`. Install the GitHub App inline; the dialog returns with repository mode pre-configured, ready to pick the repo and branch.`]})})]}),`\n`,_jsxs(_components.p,{children:[`Either path opens GitHub’s App installation flow, where you pick the organization to install on and choose which repositories the App can access. After you confirm, the installation is saved at the project level and every subsequent job can target any repository you granted access to. You can connect additional GitHub organizations at any time - each gets its own installation, and all active installations are listed in `,_jsx(_components.strong,{children:`Studio Settings → GitHub`}),`.`]}),`\n`,_jsx(Info,{children:_jsx(_components.p,{children:`Installing on an organization may require approval from a GitHub org admin if your organization restricts third-party App installs. If you don’t see your org in the picker, ask an admin to install the Frontic GitHub App for you. This approval applies per organization - when you add a second or third org, a GitHub admin for that org needs to approve it too.`})}),`\n`,`\n`,_jsxs(Frame,{children:[_jsx(OptimizedImage,{src:`https://mintcdn.com/frontic/h2E4fWn8KR2uQpFy/images/studio/settings-github-light.png?fit=max\u0026auto=format\u0026n=h2E4fWn8KR2uQpFy\u0026q=85\u0026s=e6f2deed32373b8ff1243a2cc5addd62`,className:`dark:mint-hidden mint-block`,alt:`Studio Settings - GitHub tab showing two connected GitHub organizations, each with its own Repository Access list, Manage Repositories button, and Uninstall \u0026 Disconnect action, plus an Add GitHub Organization button at the bottom`,\"data-og-width\":`2880`,width:`2880`,\"data-og-height\":`1800`,height:`1800`,\"data-path\":`images/studio/settings-github-light.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/frontic/h2E4fWn8KR2uQpFy/images/studio/settings-github-light.png?w=280\u0026fit=max\u0026auto=format\u0026n=h2E4fWn8KR2uQpFy\u0026q=85\u0026s=b4131b68b88335712217c76e6d61f148 280w, https://mintcdn.com/frontic/h2E4fWn8KR2uQpFy/images/studio/settings-github-light.png?w=560\u0026fit=max\u0026auto=format\u0026n=h2E4fWn8KR2uQpFy\u0026q=85\u0026s=afafa9c94db6cd906be911b41fbc493f 560w, https://mintcdn.com/frontic/h2E4fWn8KR2uQpFy/images/studio/settings-github-light.png?w=840\u0026fit=max\u0026auto=format\u0026n=h2E4fWn8KR2uQpFy\u0026q=85\u0026s=433d90375f506b9a525bac23d6f9e50f 840w, https://mintcdn.com/frontic/h2E4fWn8KR2uQpFy/images/studio/settings-github-light.png?w=1100\u0026fit=max\u0026auto=format\u0026n=h2E4fWn8KR2uQpFy\u0026q=85\u0026s=74e4548e3c293c35f60f9f33d2af1e78 1100w, https://mintcdn.com/frontic/h2E4fWn8KR2uQpFy/images/studio/settings-github-light.png?w=1650\u0026fit=max\u0026auto=format\u0026n=h2E4fWn8KR2uQpFy\u0026q=85\u0026s=64e07b0a3170e412d483f5181fa911d2 1650w, https://mintcdn.com/frontic/h2E4fWn8KR2uQpFy/images/studio/settings-github-light.png?w=2500\u0026fit=max\u0026auto=format\u0026n=h2E4fWn8KR2uQpFy\u0026q=85\u0026s=752bfb19db9b1df10a56e776634eb0af 2500w`}),_jsx(OptimizedImage,{src:`https://mintcdn.com/frontic/h2E4fWn8KR2uQpFy/images/studio/settings-github-dark.png?fit=max\u0026auto=format\u0026n=h2E4fWn8KR2uQpFy\u0026q=85\u0026s=4aa72b15330940400e609ca881cfcc79`,className:`mint-hidden dark:mint-block`,alt:`Studio Settings - GitHub tab showing two connected GitHub organizations, each with its own Repository Access list, Manage Repositories button, and Uninstall \u0026 Disconnect action, plus an Add GitHub Organization button at the bottom`,\"data-og-width\":`2880`,width:`2880`,\"data-og-height\":`1800`,height:`1800`,\"data-path\":`images/studio/settings-github-dark.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/frontic/h2E4fWn8KR2uQpFy/images/studio/settings-github-dark.png?w=280\u0026fit=max\u0026auto=format\u0026n=h2E4fWn8KR2uQpFy\u0026q=85\u0026s=bd7aed68d6868c52a3110d88721e98d7 280w, https://mintcdn.com/frontic/h2E4fWn8KR2uQpFy/images/studio/settings-github-dark.png?w=560\u0026fit=max\u0026auto=format\u0026n=h2E4fWn8KR2uQpFy\u0026q=85\u0026s=7794222f7357573815fe01ee2eb33146 560w, https://mintcdn.com/frontic/h2E4fWn8KR2uQpFy/images/studio/settings-github-dark.png?w=840\u0026fit=max\u0026auto=format\u0026n=h2E4fWn8KR2uQpFy\u0026q=85\u0026s=8f42fbe36895f9dd43115350778a2466 840w, https://mintcdn.com/frontic/h2E4fWn8KR2uQpFy/images/studio/settings-github-dark.png?w=1100\u0026fit=max\u0026auto=format\u0026n=h2E4fWn8KR2uQpFy\u0026q=85\u0026s=09cf6e5362ea966a683a18c60fae7f0f 1100w, https://mintcdn.com/frontic/h2E4fWn8KR2uQpFy/images/studio/settings-github-dark.png?w=1650\u0026fit=max\u0026auto=format\u0026n=h2E4fWn8KR2uQpFy\u0026q=85\u0026s=3b641c488d9ba882235265fac27226b0 1650w, https://mintcdn.com/frontic/h2E4fWn8KR2uQpFy/images/studio/settings-github-dark.png?w=2500\u0026fit=max\u0026auto=format\u0026n=h2E4fWn8KR2uQpFy\u0026q=85\u0026s=b3cd59944d4ca20be1a07c523ee69de4 2500w`})]}),`\n`,_jsxs(_components.p,{children:[`Once the App is installed, Create Job uses your connection to pre-fill the source. The dialog opens with `,_jsx(_components.strong,{children:`Source configuration`}),` collapsed - its summary line shows the current selection (a template name when no GitHub is connected, or the repository’s full name when one is). When you’ve used a repository before, that one comes back pre-selected, and the base branch field is pre-filled with the last branch you targeted. With a fresh install and a single accessible repo, that repo is picked silently. Multiple accessible repos with no history is the only case that opens with the section expanded so you can choose.`]}),`\n`,`\n`,_jsxs(Frame,{caption:`Create Job dialog with Source configuration expanded, GitHub Repository selected, the chosen repo, and the base branch selector`,children:[_jsx(OptimizedImage,{src:`https://mintcdn.com/frontic/rLUrMB73G0Gw9fyZ/images/studio/github/create-job-repository-light.png?fit=max\u0026auto=format\u0026n=rLUrMB73G0Gw9fyZ\u0026q=85\u0026s=d33771e302d053031f649b987dca341f`,className:`dark:mint-hidden mint-block mint-mx-auto mint-mt-5 mint-mb-5`,style:{maxWidth:`480px`},alt:`Create Job dialog showing the Name field and an expanded Source configuration section with a Template / GitHub Repository toggle set to GitHub Repository, the chosen repo with a Change action, and a Base Branch dropdown set to main`,\"data-og-width\":`1152`,width:`1152`,\"data-og-height\":`1376`,height:`1376`,\"data-path\":`images/studio/github/create-job-repository-light.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/frontic/rLUrMB73G0Gw9fyZ/images/studio/github/create-job-repository-light.png?w=280\u0026fit=max\u0026auto=format\u0026n=rLUrMB73G0Gw9fyZ\u0026q=85\u0026s=e71dba58ed1444376ee6cbd6dbefa60a 280w, https://mintcdn.com/frontic/rLUrMB73G0Gw9fyZ/images/studio/github/create-job-repository-light.png?w=560\u0026fit=max\u0026auto=format\u0026n=rLUrMB73G0Gw9fyZ\u0026q=85\u0026s=825f85b8227e583a6fd4ee1d94a72290 560w, https://mintcdn.com/frontic/rLUrMB73G0Gw9fyZ/images/studio/github/create-job-repository-light.png?w=840\u0026fit=max\u0026auto=format\u0026n=rLUrMB73G0Gw9fyZ\u0026q=85\u0026s=1f800676480eb9830e9003d61951b08c 840w, https://mintcdn.com/frontic/rLUrMB73G0Gw9fyZ/images/studio/github/create-job-repository-light.png?w=1100\u0026fit=max\u0026auto=format\u0026n=rLUrMB73G0Gw9fyZ\u0026q=85\u0026s=03afea325708c865f7bb1c968cd924e3 1100w, https://mintcdn.com/frontic/rLUrMB73G0Gw9fyZ/images/studio/github/create-job-repository-light.png?w=1650\u0026fit=max\u0026auto=format\u0026n=rLUrMB73G0Gw9fyZ\u0026q=85\u0026s=b258efd8ca844f0f3f3cac7fdc250be5 1650w, https://mintcdn.com/frontic/rLUrMB73G0Gw9fyZ/images/studio/github/create-job-repository-light.png?w=2500\u0026fit=max\u0026auto=format\u0026n=rLUrMB73G0Gw9fyZ\u0026q=85\u0026s=cde90fe9beb4688a6474513112f2fc0b 2500w`}),_jsx(OptimizedImage,{src:`https://mintcdn.com/frontic/rLUrMB73G0Gw9fyZ/images/studio/github/create-job-repository-dark.png?fit=max\u0026auto=format\u0026n=rLUrMB73G0Gw9fyZ\u0026q=85\u0026s=15c4c3d50c112fd7fcb6225c60ba0504`,className:`mint-hidden dark:mint-block mint-mx-auto mint-mt-5 mint-mb-5`,style:{maxWidth:`480px`},alt:`Create Job dialog showing the Name field and an expanded Source configuration section with a Template / GitHub Repository toggle set to GitHub Repository, the chosen repo with a Change action, and a Base Branch dropdown set to main`,\"data-og-width\":`1152`,width:`1152`,\"data-og-height\":`1376`,height:`1376`,\"data-path\":`images/studio/github/create-job-repository-dark.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/frontic/rLUrMB73G0Gw9fyZ/images/studio/github/create-job-repository-dark.png?w=280\u0026fit=max\u0026auto=format\u0026n=rLUrMB73G0Gw9fyZ\u0026q=85\u0026s=fff74f8d572e2e456fa4b547212a1b18 280w, https://mintcdn.com/frontic/rLUrMB73G0Gw9fyZ/images/studio/github/create-job-repository-dark.png?w=560\u0026fit=max\u0026auto=format\u0026n=rLUrMB73G0Gw9fyZ\u0026q=85\u0026s=947a500444e1e2b071f3a2275c8683f4 560w, https://mintcdn.com/frontic/rLUrMB73G0Gw9fyZ/images/studio/github/create-job-repository-dark.png?w=840\u0026fit=max\u0026auto=format\u0026n=rLUrMB73G0Gw9fyZ\u0026q=85\u0026s=296cb774be2587a7f2323ffa5697f0df 840w, https://mintcdn.com/frontic/rLUrMB73G0Gw9fyZ/images/studio/github/create-job-repository-dark.png?w=1100\u0026fit=max\u0026auto=format\u0026n=rLUrMB73G0Gw9fyZ\u0026q=85\u0026s=3a07ffe51045efc65bb7f9839f6bd89c 1100w, https://mintcdn.com/frontic/rLUrMB73G0Gw9fyZ/images/studio/github/create-job-repository-dark.png?w=1650\u0026fit=max\u0026auto=format\u0026n=rLUrMB73G0Gw9fyZ\u0026q=85\u0026s=7a0e8f3fe542a07a3774617c7fed78dd 1650w, https://mintcdn.com/frontic/rLUrMB73G0Gw9fyZ/images/studio/github/create-job-repository-dark.png?w=2500\u0026fit=max\u0026auto=format\u0026n=rLUrMB73G0Gw9fyZ\u0026q=85\u0026s=f63f893ae44cee2798730e316acbe1fc 2500w`})]}),`\n`,_jsx(Heading,{level:`3`,id:`repository-access`,children:`Repository access`}),`\n`,_jsxs(_components.p,{children:[`After the App is installed, each connected organization shows its own `,_jsx(_components.strong,{children:`Repository Access`}),` panel in Studio Settings listing the repositories Studio can see for that org. The list is paginated - load more if you have many repos. If you have multiple organizations connected, each appears as its own installation card with its own Repository Access panel.`]}),`\n`,_jsxs(_components.p,{children:[`To change which repositories the App can access for an org, click `,_jsx(_components.strong,{children:`Manage Repositories`}),` on that org’s installation card. That redirects you to the GitHub App’s installation settings on GitHub, where you can add or remove repositories. Save there, and GitHub redirects you back to Studio with the new list. Changes apply immediately for everyone on the project.`]}),`\n`,_jsx(_components.p,{children:`Use this when:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`A new repository was created after the App was installed and isn’t in the picker yet`}),`\n`,_jsx(_components.li,{children:`You want to scope Studio to a narrower set of repos than what’s currently granted`}),`\n`,_jsx(_components.li,{children:`You’re auditing what Studio has access to`}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`what-studio-does-with-the-connection`,children:`What Studio does with the connection`}),`\n`,_jsx(_components.p,{children:`When a job runs against a GitHub repository:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`The workspace `,_jsx(_components.strong,{children:`clones the repo`}),` when the job starts`]}),`\n`,_jsxs(_components.li,{children:[`The Studio chat creates `,_jsx(_components.strong,{children:`a new branch`}),` off the base branch you pick`]}),`\n`,_jsx(_components.li,{children:`Every file edit is a change on that branch`}),`\n`,_jsx(_components.li,{children:`Clicking Commit in the Changes panel commits on the branch and pushes to GitHub in one step`}),`\n`,_jsx(_components.li,{children:`Pull requests target the base branch`}),`\n`]}),`\n`,_jsx(_components.p,{children:`Everything is standard Git. Commits are authored by the GitHub App, not by the teammate who ran the job - so don’t use the commit author field for attribution.`}),`\n`,_jsx(Heading,{level:`3`,id:`multi-repository-projects`,children:`Multi-repository projects`}),`\n`,_jsx(_components.p,{children:`Each Studio job picks its own repository and base branch at creation - there’s no per-project default repository to override. If your team maintains multiple frontends (web storefront, mobile app, admin surface) against the same Frontic project, each can live in its own repo - including repos across different GitHub organizations if you have multiple orgs connected - and jobs target whichever one you’re working on.`}),`\n`,_jsx(Heading,{level:`3`,id:`revoking-access`,children:`Revoking access`}),`\n`,_jsx(_components.p,{children:`Two ways:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`From Frontic`}),` - Go to `,_jsx(_components.strong,{children:`Studio Settings → GitHub`}),` and click `,_jsx(_components.strong,{children:`Uninstall \u0026 Disconnect`}),` on the installation you want to remove. Each connected organization is disconnected independently - removing one does not affect other connected organizations. Existing jobs that target that org’s repositories finish; no new jobs can be created against those repositories until the App is reinstalled.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`From GitHub`}),` - in your organization’s `,_jsx(_components.strong,{children:`Settings → GitHub Apps → Frontic Studio`}),`, click `,_jsx(_components.strong,{children:`Uninstall`}),`. GitHub enforces immediately.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`Neither deletes already-committed work - that’s in your Git history and belongs to you.`}),`\n`,_jsx(Heading,{level:`2`,id:`create-a-repository-from-a-job`,children:`Create a repository from a job`}),`\n`,_jsxs(_components.p,{children:[`Not every job starts from GitHub. When you scaffold a job from a `,_jsx(_components.a,{href:`/studio/frontic-studio`,children:`framework template`}),` (Nuxt or Next.js), the `,_jsx(_components.a,{href:`/studio/workspace`,children:`workspace`}),` has no repository connected. `,_jsx(_components.strong,{children:`Create Repository`}),` enables you to create a new GitHub repository from a template job in one step.`]}),`\n`,_jsxs(_components.p,{children:[`The action only appears while the job has `,_jsx(_components.strong,{children:`no repository connected`}),`. You’ll find it in two places: the workspace panel toolbar, and the `,_jsx(_components.a,{href:`/studio/workspace#the-changes-panel`,children:`Changes panel`}),`, which shows it in place of the file list until a repository exists. Both open the same dialog.`]}),`\n`,_jsx(Heading,{level:`3`,id:`before-you-start`,children:`Before you start`}),`\n`,_jsx(_components.p,{children:`Two things must be in place:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`GitHub connected at the project level`}),` - the Frontic GitHub App is installed (see `,_jsx(_components.a,{href:`#connecting-github`,children:`Connecting GitHub`}),`).`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`At least one organization installation`}),` - the org picker lists GitHub `,_jsx(_components.em,{children:`organizations`}),` only. Personal GitHub accounts aren’t supported here. If your only installation is a personal account, connect an organization from `,_jsx(_components.strong,{children:`Studio Settings → GitHub`}),` first.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`The dialog handles the gaps for you. If GitHub isn’t connected at all, it shows an inline `,_jsx(_components.strong,{children:`Connect GitHub`}),` prompt - the same install flow as `,_jsx(_components.a,{href:`#connecting-github`,children:`Studio Settings or Create Job`}),`. If GitHub is connected but no organization is available, it links you to `,_jsx(_components.strong,{children:`Studio Settings → GitHub`}),` to add one.`]}),`\n`,_jsx(Heading,{level:`3`,id:`creating-the-repository`,children:`Creating the repository`}),`\n`,_jsxs(Steps,{children:[_jsx(Step,{title:`Open Create Repository`,icon:`plus`,children:_jsxs(_components.p,{children:[`Click `,_jsx(_components.strong,{children:`Create Repository`}),` in the workspace panel toolbar or in the\nChanges panel.`]})}),_jsx(Step,{title:`Pick the organization`,icon:`building`,children:_jsx(_components.p,{children:`Choose the GitHub organization to create the repository under. When\nonly one organization is connected, it’s pre-selected.`})}),_jsx(Step,{title:`Name the repository`,icon:`pen`,children:_jsx(_components.p,{children:`Enter a name - letters, numbers, hyphens, underscores, and dots, 1–100\ncharacters. Add an optional description if you like.`})}),_jsx(Step,{title:`Choose visibility`,icon:`lock`,children:_jsxs(_components.p,{children:[`The repository is `,_jsx(_components.strong,{children:`private`}),` by default. Flip the toggle to make it\npublic.`]})}),_jsx(Step,{title:`Confirm`,icon:`check`,children:_jsx(_components.p,{children:`Studio creates the repository under the organization, pushes the\ncurrent workspace as the initial commit, and connects it to the job.`})})]}),`\n`,_jsxs(_components.p,{children:[`Once it’s done, the job is a normal GitHub-backed job: the `,_jsx(_components.a,{href:`/studio/workspace#the-changes-panel`,children:`Changes panel`}),` is live, and the full `,_jsx(_components.a,{href:`#commit`,children:`Commit`}),` → push → `,_jsx(_components.a,{href:`#open-a-pull-request`,children:`open a pull request`}),` flow works exactly as it does for a job that started from an existing repository.`]}),`\n`,_jsx(Info,{children:_jsxs(_components.p,{children:[`The repository is created empty and your current workspace lands as the first commit on the default branch (`,_jsx(_components.code,{children:`main`}),`). There’s no separate base branch to choose - this flow both creates the repo and pushes to it in one confirm.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`commit`,children:`Commit`}),`\n`,_jsxs(_components.p,{children:[`Once Studio has made file changes you’re happy with, commit them from the workspace. The `,_jsx(_components.a,{href:`/studio/workspace`,children:`Workspace`}),` page covers reviewing the diffs in detail; this section covers the commit mechanics.`]}),`\n`,_jsxs(Steps,{children:[_jsx(Step,{title:`Review the diffs`,icon:`eye`,children:_jsx(_components.p,{children:`Before committing, open the Changes panel and read every file - not\nonly the ones you expected. Agents sometimes touch imports, shared\nutilities, or generated files you didn’t mention. Worth knowing\nwhat landed.`})}),_jsx(Step,{title:`Review or write a commit message`,icon:`pen`,children:_jsx(_components.p,{children:`Studio drafts a commit message from the diff as soon as the dialog\nopens. If you want to write your own commit message, just start\ntyping - your text is kept and the suggestion is dropped.`})}),_jsx(Step,{title:`Confirm the target branch`,icon:`code-branch`,children:_jsxs(_components.p,{children:[`The dialog has a `,_jsx(_components.strong,{children:`Commit changes to`}),` row that shows the branch\nthe commit will land on - the workspace’s feature branch by default.\nClick the row to expand it and switch to a different existing branch\nor create a new one (under the hood it’s the standard branch\nselector with `,_jsx(_components.strong,{children:`Existing branch`}),` and `,_jsx(_components.strong,{children:`Create new branch`}),`\noptions). Leave it collapsed when the default is right.`]})}),_jsx(Step,{title:`Click Commit`,icon:`check`,children:_jsx(_components.p,{children:`Studio commits on the branch and pushes to GitHub in one step. The\nfirst commit creates the branch on GitHub; later commits fast-forward\nit. The Changes panel shows the branch up to date with remote when\nit’s done.`})})]}),`\n`,_jsx(Heading,{level:`2`,id:`open-a-pull-request`,children:`Open a pull request`}),`\n`,_jsxs(_components.p,{children:[`When a commit moves the job onto a new branch - usually your first commit to the feature branch - the success notification offers `,_jsx(_components.strong,{children:`Create Pull Request`}),`. It opens GitHub’s compare page from the branch the job was on to the one you just committed to, with the pull request already drafted:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Title`}),` - the first line of your commit message.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Description`}),` - a short changelog Studio writes from the job’s conversation and the committed changes: what changed and what it enables, in plain language, without file names or Git jargon.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`Both land in GitHub’s own form, so edit or replace them, add the context your team needs (ticket links, screenshots, test notes), and create the PR as you normally would. If the description can’t be written within a few seconds, the page opens with only the title filled in and you write the description yourself. Later commits to the same branch don’t offer the action again; open the PR from GitHub if you skipped it.`}),`\n`,_jsx(Tip,{children:_jsxs(_components.p,{children:[`Spend 30 seconds on the drafted description before you create the PR. It says `,_jsx(_components.em,{children:`what`}),` changed; add `,_jsx(_components.em,{children:`why`}),` it changed and `,_jsx(_components.em,{children:`what to look at first`}),`. A good description saves more review time than it takes to write.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`merging-and-cleanup`,children:`Merging and cleanup`}),`\n`,_jsx(_components.p,{children:`When the PR is approved and CI is green, merge it like any other PR. After merge:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`The feature branch can be deleted (your team’s usual branch cleanup applies)`}),`\n`,_jsx(_components.li,{children:`The Studio job stays around - you can reopen it later for follow-up work in the same workspace`}),`\n`,_jsxs(_components.li,{children:[`If the change involved stack configuration (new blocks, listings, pages) that went through a preview `,_jsx(_components.a,{href:`/releases/overview`,children:`release`}),`, promote the preview if you haven’t already`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`coordinating-with-releases`,children:`Coordinating with releases`}),`\n`,_jsxs(_components.p,{children:[`A PR is about code. A `,_jsx(_components.a,{href:`/releases/overview`,children:`release`}),` is about stack config. When a change involves both - which most meaningful changes do - the order matters:`]}),`\n`,_jsxs(Steps,{children:[_jsx(Step,{title:`Preview the stack change first`,icon:`eye`,children:_jsx(_components.p,{children:`Create a preview in the admin app so the stack state is frozen.`})}),_jsx(Step,{title:`Generate the Client SDK against the preview`,icon:`code`,children:_jsxs(_components.p,{children:[`Run `,_jsx(_components.code,{children:`frontic generate --env preview`}),` (or `,_jsx(_components.code,{children:`frontic generate`}),` and pick\n`,_jsx(_components.strong,{children:`preview`}),` from the prompt). The SDK embeds a version token pointing\nat the preview.`]})}),_jsx(Step,{title:`Commit the SDK + frontend code`,icon:`code-commit`,children:_jsx(_components.p,{children:`Commit the generated client files alongside the frontend code that\nuses them. Push the branch.`})}),_jsx(Step,{title:`Open the PR`,icon:`code-pull-request`,children:_jsxs(_components.p,{children:[`Mention in the description that there’s an accompanying preview\nrelease and link to it. Reviewers need to know the PR depends on\nstack state that isn’t `,_jsx(_components.code,{children:`public`}),` yet.`]})}),_jsx(Step,{title:`Deploy the PR to a preview environment`,icon:`cloud-arrow-up`,children:_jsx(_components.p,{children:`Your deploy pipeline builds a preview deploy. Because the SDK in\nthe branch carries the preview token, the preview deploy talks to\nthe Frontic preview - so QA validates the full stack, not only\nthe code.`})}),_jsx(Step,{title:`Merge the PR`,icon:`check`,children:_jsx(_components.p,{children:`Production deploys the new frontend. Because the SDK carries the\npreview token, production is now talking to the Frontic preview -\nso real traffic hits the validated stack state.`})}),_jsx(Step,{title:`Promote the Frontic preview`,icon:`rocket`,children:_jsxs(_components.p,{children:[`Promote the preview to `,_jsx(_components.code,{children:`public`}),`. The preview version becomes the\nnew public; the token your frontend is pinned to falls back to\n`,_jsx(_components.code,{children:`public`}),` gracefully - same content, no code change needed.`]})})]}),`\n`,_jsxs(_components.p,{children:[`The preview-then-promote sequence gives you a QA checkpoint where the frontend `,_jsx(_components.em,{children:`and`}),` stack state are both frozen, so you’re not chasing a moving target. For a worked example, see `,_jsx(_components.a,{href:`/essentials/your-first-feature`,children:`Your First Feature`}),`.`]}),`\n`,_jsx(Info,{children:_jsxs(_components.p,{children:[`Preview - the next iteration of this flow pairs a `,_jsx(_components.a,{href:`/releases/overview#drafts`,children:`draft`}),` with the Studio job and the PR, so the stack sandbox, the frontend code, and the release that ships both move together. In preview today; expanding as it matures.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`troubleshooting`,children:`Troubleshooting`}),`\n`,_jsxs(AccordionGroup,{children:[_jsx(Accordion,{title:`My repository isn't showing up in the picker`,id:`my-repository-isnt-showing-up-in-the-picker`,children:_jsxs(_components.p,{children:[`The repository wasn’t included in the App’s repository access grant.\nIn `,_jsx(_components.strong,{children:`Studio Settings → GitHub`}),`, click `,_jsx(_components.strong,{children:`Manage Repositories`}),` to\nopen the GitHub App’s installation settings, add the missing repo,\nand save. The picker refreshes with the new list.`]})}),_jsx(Accordion,{title:`The GitHub App installation didn't complete`,id:`the-github-app-installation-didnt-complete`,children:_jsxs(_components.p,{children:[`Most often this is an organization permissions issue: the org\nrequires admin approval for third-party App installs, and the\nrequest is still pending. Ask a GitHub org admin to approve (or\ninstall) the Frontic Studio App for the organization. If you\ncancelled the install partway through, just click `,_jsx(_components.strong,{children:`Install GitHub\nApp`}),` again.`]})}),_jsx(Accordion,{title:`A teammate can't push to GitHub from Studio`,id:`a-teammate-cant-push-to-github-from-studio`,children:_jsxs(_components.p,{children:[`Once the App is installed on the org, every teammate on the Frontic\nproject gets Git access - no per-user GitHub setup is required. If\na teammate is blocked, check that the repository they’re working on\nis included in the App’s repository access (see `,_jsx(_components.strong,{children:`Manage\nRepositories`}),`) and that they have the Frontic permissions to use\nStudio in this project.`]})}),_jsxs(Accordion,{title:`Connecting a GitHub organization that's already connected to another Frontic team`,id:`connecting-a-github-organization-thats-already-connected-to-another-frontic-team`,children:[_jsxs(_components.p,{children:[`Supported. From the second Frontic team, go to `,_jsx(_components.strong,{children:`Studio Settings → GitHub`}),`\nand click `,_jsx(_components.strong,{children:`Install GitHub App`}),`, then complete\nthe GitHub App authorization flow. When GitHub redirects back,\nFrontic detects that the same installation is being attached to a\nnew Frontic team and finalises the connection. Both Frontic\nteams can then target repositories under the same GitHub\norganization independently - each has its own repository access\nsettings and its own job and workspace history.`]}),_jsxs(_components.p,{children:[`Note: this is distinct from connecting `,_jsx(_components.em,{children:`multiple`}),` GitHub organizations to a single Frontic project - use the `,_jsx(_components.strong,{children:`Add GitHub Organization`}),` button in Studio Settings → GitHub for that.`]})]}),_jsx(Accordion,{title:`Create Repository fails saying the App can't create repositories in this organization`,id:`create-repository-fails-saying-the-app-cant-create-repositories-in-this-organization`,children:_jsxs(_components.p,{children:[`The Frontic GitHub App installation for that organization doesn’t have\npermission to create repositories. Reconfigure the installation to\ngrant repository administration access - in `,_jsx(_components.strong,{children:`Studio Settings →\nGitHub`}),`, use `,_jsx(_components.strong,{children:`Manage Repositories`}),` on that org’s card to open its\nGitHub App settings, then approve the added permission (a GitHub org\nadmin may need to do this). Once granted, reopen the dialog and try\nagain.`]})}),_jsx(Accordion,{title:`I connected a second GitHub org but its repositories aren't showing in the picker`,id:`i-connected-a-second-github-org-but-its-repositories-arent-showing-in-the-picker`,children:_jsxs(_components.p,{children:[`The GitHub App installation for that org may not include the repositories you need. In `,_jsx(_components.strong,{children:`Studio Settings → GitHub`}),`, find the installation card for the org you just added and click `,_jsx(_components.strong,{children:`Manage Repositories`}),`. This opens the GitHub App’s installation settings for that org, where you can add the missing repositories and save. The picker refreshes immediately.`]})})]}),`\n`,_jsx(Heading,{level:`2`,id:`related`,children:`Related`}),`\n`,_jsxs(CardGroup,{cols:2,children:[_jsx(Card,{title:`Release Control`,icon:`code-merge`,href:`/releases/overview`,children:_jsx(_components.p,{children:`How the stack-side of your changes moves between stages. (Plus plan.)`})}),_jsx(Card,{title:`Studio`,icon:`sparkles`,href:`/studio/frontic-studio`,children:_jsx(_components.p,{children:`Where chat-driven changes happen before they hit the connected\nrepository.`})})]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"codeStyling":{"theme":"css-variables"},"config":{},"pageMetadata":{"title":"GitHub Integration","icon":"github","description":null,"href":"/studio/github-integration"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Connecting GitHub","slug":"connecting-github","depth":2,"children":[{"title":"Repository access","slug":"repository-access","depth":3,"children":[]},{"title":"What Studio does with the connection","slug":"what-studio-does-with-the-connection","depth":3,"children":[]},{"title":"Multi-repository projects","slug":"multi-repository-projects","depth":3,"children":[]},{"title":"Revoking access","slug":"revoking-access","depth":3,"children":[]}]},{"title":"Create a repository from a job","slug":"create-a-repository-from-a-job","depth":2,"children":[{"title":"Before you start","slug":"before-you-start","depth":3,"children":[]},{"title":"Creating the repository","slug":"creating-the-repository","depth":3,"children":[]}]},{"title":"Commit","slug":"commit","depth":2,"children":[]},{"title":"Open a pull request","slug":"open-a-pull-request","depth":2,"children":[]},{"title":"Merging and cleanup","slug":"merging-and-cleanup","depth":2,"children":[]},{"title":"Coordinating with releases","slug":"coordinating-with-releases","depth":2,"children":[]},{"title":"Troubleshooting","slug":"troubleshooting","depth":2,"children":[]},{"title":"Related","slug":"related","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"dynamicCss":".mint-mx-auto {\n margin-left: auto;\n margin-right: auto\n}\n.mint-mb-5 {\n margin-bottom: 1.25rem\n}\n.mint-mt-5 {\n margin-top: 1.25rem\n}\n.mint-block {\n display: block\n}\n.mint-hidden {\n display: none\n}\n.dark\\:mint-block:is(.dark *) {\n display: block\n}\n.dark\\:mint-hidden:is(.dark *) {\n display: none\n}","subdomain":"frontic","siteName":"Frontic Docs","title":"GitHub Integration - Frontic Docs","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-01T22:42:14.307Z","originalFileLocation":"studio/github-integration.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"dark\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"application-name\" content=\"Frontic Docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/frontic/J-QaW07dTW_FQ00e/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/frontic/J-QaW07dTW_FQ00e/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/frontic/J-QaW07dTW_FQ00e/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/frontic/J-QaW07dTW_FQ00e/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/frontic/J-QaW07dTW_FQ00e/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/frontic/J-QaW07dTW_FQ00e/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/frontic/J-QaW07dTW_FQ00e/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/frontic/J-QaW07dTW_FQ00e/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/frontic/J-QaW07dTW_FQ00e/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"GitHub Integration - Frontic Docs\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Frontic Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.frontic.com/studio/github-integration\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://frontic.mintlify.app/_mintlify/api/og/v2?division=Frontic+Studio\u0026amp;title=GitHub+Integration\u0026amp;theme=206c460697bb939e13b9c293\u0026amp;signature=08e3dc5ef07602d5d5bb5b7ae37204c817817c343760afea08df304ec5e351b7\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"GitHub Integration - Frontic Docs\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://frontic.mintlify.app/_mintlify/api/og/v2?division=Frontic+Studio\u0026amp;title=GitHub+Integration\u0026amp;theme=206c460697bb939e13b9c293\u0026amp;signature=08e3dc5ef07602d5d5bb5b7ae37204c817817c343760afea08df304ec5e351b7\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/frontic/J-QaW07dTW_FQ00e/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Frontic Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#a855f7\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.frontic.com/studio/github-integration\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/studio/github-integration.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.frontic.com/#organization\",\"name\":\"Frontic Docs\",\"url\":\"https://docs.frontic.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/frontic/QEEg-J3fIyHJ_Wyh/logo/logo-light.svg?fit=max\u0026auto=format\u0026n=QEEg-J3fIyHJ_Wyh\u0026q=85\u0026s=36391b9f3546193a73f97d7b6ee40463\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.frontic.com#website\",\"name\":\"Frontic Docs\",\"url\":\"https://docs.frontic.com\",\"publisher\":{\"@id\":\"https://docs.frontic.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.frontic.com/studio/github-integration#webpage\",\"url\":\"https://docs.frontic.com/studio/github-integration\",\"name\":\"GitHub Integration\",\"dateModified\":\"2026-11-01T22:42:14.307Z\",\"isPartOf\":{\"@id\":\"https://docs.frontic.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.frontic.com/studio/github-integration#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.frontic.com/studio/github-integration#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Build in Frontic\",\"item\":\"https://docs.frontic.com/build/overview\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Frontic Studio\",\"item\":\"https://docs.frontic.com/studio/frontic-studio\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"GitHub Integration\",\"item\":\"https://docs.frontic.com/studio/github-integration\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.frontic.com/studio/github-integration#article\",\"headline\":\"GitHub Integration\",\"name\":\"GitHub Integration\",\"url\":\"https://docs.frontic.com/studio/github-integration\",\"mainEntityOfPage\":{\"@id\":\"https://docs.frontic.com/studio/github-integration#webpage\"},\"dateModified\":\"2026-11-01T22:42:14.307Z\",\"publisher\":{\"@id\":\"https://docs.frontic.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.frontic.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Frontic Docs\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Frontic Docs","nav":{"global":{},"tabs":[{"tab":"Documentation","groups":[{"group":"Essentials","pages":[{"title":"What is Frontic","icon":"house","href":"/essentials/what-is-frontic"},{"title":"Quick Setup","icon":"bolt","href":"/essentials/quick-setup"},{"title":"Your First Feature","icon":"rocket","href":"/essentials/your-first-feature"},{"title":"Core Concepts","icon":"book","href":"/essentials/core-concepts"},{"title":"AI Buddy","icon":"user-astronaut","href":"/essentials/buddy"},{"title":"Keyboard Shortcuts","icon":"keyboard","href":"/essentials/keyboard-shortcuts"},{"title":"Your turn","sidebarTitle":"Your turn","icon":"bell","href":"/essentials/your-turn"}]},{"group":"Commerce Concepts","pages":[{"title":"Product Models","icon":"boxes-stacked","href":"/commerce-concepts/product-models"},{"title":"Multi-Channel \u0026 Multi-Region","icon":"globe","href":"/commerce-concepts/multi-channel-region"},{"title":"URLs, Redirects \u0026 SEO","icon":"link","href":"/commerce-concepts/urls-seo"}]},{"group":"Data Integration","pages":[{"title":"Overview","icon":"circle-nodes","href":"/data-integration/overview"},{"title":"Ingest Data","icon":"gears","iconType":"solid","href":"/data-integration/ingest"},{"title":"Data Storages","icon":"database","href":"/data-integration/data-storages"},{"title":"Value Composer","icon":"wand-magic-sparkles","href":"/data-integration/value-composer"}]},{"group":"API Builder","pages":[{"title":"Overview","icon":"sitemap","href":"/api-builder/overview"},{"title":"Detail Blocks","icon":"cube","iconType":"solid","href":"/api-builder/blocks"},{"title":"Search Listings","icon":"cubes","iconType":"solid","href":"/api-builder/listings"},{"title":"Page URLs","icon":"map","href":"/api-builder/pages"},{"title":"Menu Trees","icon":"list-tree","iconType":"solid","href":"/api-builder/trees"}]},{"group":"Release Control","pages":[{"title":"Overview","icon":"code-merge","tag":"Plus","href":"/releases/overview"},{"title":"What's in a Release","icon":"list-check","href":"/releases/what-flows-through"},{"title":"Release Flow","icon":"layer-group","href":"/releases/release-flow"}]},{"group":"Build in Frontic","pages":[{"title":"Overview","icon":"hammer","href":"/build/overview"},{"group":"Frontic Studio","pages":[{"title":"Frontic Studio","icon":"sparkles","iconType":"solid","href":"/studio/frontic-studio"},{"title":"Workspace","icon":"laptop-code","description":null,"href":"/studio/workspace"},{"title":"GitHub Integration","icon":"github","href":"/studio/github-integration"},{"title":"Studio Settings","icon":"gear","description":null,"href":"/studio/settings"}]},{"group":"Experience Designer","pages":[{"title":"Overview","icon":"palette","tag":"Preview","href":"/designer/overview"},{"title":"Building an experience","icon":"pen-ruler","tag":"Preview","href":"/designer/building"},{"title":"Publishing","icon":"rocket","tag":"Preview","href":"/designer/publishing"}]}]},{"group":"Build in Your IDE","pages":[{"title":"Overview","icon":"code","href":"/ide/overview"},{"title":"Project Context","icon":"brain","href":"/ide/project-context"},{"title":"Frontic CLI","icon":"terminal","href":"/ide/frontic-cli"},{"title":"MCP Tools","icon":"microchip-ai","href":"/ide/mcp-tools"}]},{"group":"Context Base","pages":[{"title":"Overview","icon":"brain","tag":"Grow","href":"/context-base/overview"},{"title":"Context Setup","sidebarTitle":"Setup","icon":"wand-magic-sparkles","tag":"Preview","href":"/context-base/setup"},{"title":"Skills","icon":"star","href":"/context-base/skills"},{"title":"Rules","icon":"gavel","href":"/context-base/rules"},{"title":"Commands","icon":"terminal","href":"/context-base/commands"},{"title":"Guides","icon":"book","href":"/context-base/guides"},{"title":"Design Library","icon":"palette","href":"/context-base/design-library"}]},{"group":"Project Settings","pages":[{"title":"General","icon":"folder-gear","href":"/project-settings/general"},{"title":"Scopes","icon":"layer-group","href":"/project-settings/scopes"},{"title":"Regions","icon":"earth-americas","href":"/project-settings/regions"},{"title":"Locales","icon":"language","href":"/project-settings/locales"},{"title":"Domains","icon":"globe","href":"/project-settings/domains"},{"title":"Data Types","icon":"table","href":"/project-settings/data-types"},{"title":"Agents","icon":"robot","href":"/project-settings/agents"}]},{"group":"Administration","pages":[{"title":"Teams","icon":"building","href":"/admin/teams"},{"title":"Members \u0026 Roles","icon":"users","href":"/admin/members-and-roles"},{"title":"Billing \u0026 Plans","icon":"credit-card","href":"/admin/billing-and-plans"},{"title":"Limits","icon":"clock","href":"/admin/limits"}]}]},{"tab":"Connectors","pages":[{"title":"Connectors","href":"/connectors/overview"}]},{"tab":"Reference","pages":[{"title":"Reference","href":"/reference/overview"}]}]},"basePath":"","title":"GitHub Integration - Frontic Docs","buildId":"dpl_36EDyZCDfRuoUD9af5CH4M1bqY2h","deploymentId":"dpl_36EDyZCDfRuoUD9af5CH4M1bqY2h","dynamics":["07c022d89b","a74be98ba7"],"chunks":["Frame-DW6UFrUy.js","DynamicMarkdown-B62XqCSI.js","zoom-image-lightbox-eHyQ0tlO.js","lightbox-handle-r17bVUz3.js"]}