Showing preview only (4,360K chars total). Download the full file or copy to clipboard to get everything.
Repository: payloadcms/website
Branch: main
Commit: 984a47bd28c1
Files: 1076
Total size: 3.9 MB
Directory structure:
gitextract_uabekduh/
├── .github/
│ └── workflows/
│ └── on-payload-release.yml
├── .gitignore
├── .prettierignore
├── .prettierrc.json
├── .vscode/
│ ├── extensions.json
│ └── settings.json
├── Caddyfile
├── LICENSE
├── README.md
├── algolia.d.ts
├── cssVariables.cjs
├── eslint.config.js
├── next-sitemap.config.cjs
├── next.config.js
├── package.json
├── public/
│ ├── js/
│ │ └── theme.js
│ ├── llms-full.txt
│ ├── llms.txt
│ ├── robots.txt
│ ├── sitemap-0.xml
│ └── sitemap.xml
├── redirects.js
├── src/
│ ├── access/
│ │ ├── isAdmin.ts
│ │ ├── isAdminOrSelf.ts
│ │ └── publishedOnly.ts
│ ├── access.ts
│ ├── adapters/
│ │ ├── AlgoliaPagination/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ └── AlgoliaSearchBox/
│ │ ├── index.module.scss
│ │ └── index.tsx
│ ├── app/
│ │ ├── (frontend)/
│ │ │ ├── (cloud)/
│ │ │ │ ├── cloud/
│ │ │ │ │ ├── (tabs)/
│ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ ├── page.module.scss
│ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ ├── page_client.tsx
│ │ │ │ │ │ ├── settings/
│ │ │ │ │ │ │ ├── DeletionConfirmationForm/
│ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ └── page.module.scss
│ │ │ │ │ │ │ ├── layout.module.scss
│ │ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ │ ├── page.module.scss
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ └── page_client.tsx
│ │ │ │ │ │ └── teams/
│ │ │ │ │ │ ├── page.module.scss
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── [team-slug]/
│ │ │ │ │ │ ├── (tabs)/
│ │ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ │ ├── page.module.scss
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ ├── page_client.tsx
│ │ │ │ │ │ │ └── settings/
│ │ │ │ │ │ │ ├── (tabs)/
│ │ │ │ │ │ │ │ ├── billing/
│ │ │ │ │ │ │ │ │ ├── page.module.scss
│ │ │ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ │ │ └── useCustomerPortal.tsx
│ │ │ │ │ │ │ │ ├── invoices/
│ │ │ │ │ │ │ │ │ ├── page.module.scss
│ │ │ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ │ │ ├── page_client.tsx
│ │ │ │ │ │ │ │ │ └── useInvoices.ts
│ │ │ │ │ │ │ │ ├── members/
│ │ │ │ │ │ │ │ │ ├── UpdateRolesConfirmationForm/
│ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ └── page.module.scss
│ │ │ │ │ │ │ │ │ ├── page.module.scss
│ │ │ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ │ │ └── page_client.tsx
│ │ │ │ │ │ │ │ └── subscriptions/
│ │ │ │ │ │ │ │ ├── page.module.scss
│ │ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ │ ├── page_client.tsx
│ │ │ │ │ │ │ │ ├── reducer.ts
│ │ │ │ │ │ │ │ └── useSubscriptions.ts
│ │ │ │ │ │ │ ├── TeamBillingMessages/
│ │ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ ├── layout.module.scss
│ │ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ │ ├── page.module.scss
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ └── page_client.tsx
│ │ │ │ │ │ └── [project-slug]/
│ │ │ │ │ │ ├── (tabs)/
│ │ │ │ │ │ │ ├── (overview)/
│ │ │ │ │ │ │ │ ├── DeploymentLogs/
│ │ │ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ ├── InfraOffline/
│ │ │ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ ├── InfraOnline/
│ │ │ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ │ ├── ProjectBillingMessages/
│ │ │ │ │ │ │ │ ├── BadSubscription.tsx
│ │ │ │ │ │ │ │ ├── MissingPaymentMethod.tsx
│ │ │ │ │ │ │ │ ├── TrialMessage.tsx
│ │ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ ├── database/
│ │ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ │ └── page_client.tsx
│ │ │ │ │ │ │ ├── file-storage/
│ │ │ │ │ │ │ │ ├── page.module.scss
│ │ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ │ └── page_client.tsx
│ │ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ │ ├── logs/
│ │ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ │ └── page_client.tsx
│ │ │ │ │ │ │ └── settings/
│ │ │ │ │ │ │ ├── (build-settings)/
│ │ │ │ │ │ │ │ ├── page.module.scss
│ │ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ │ └── page_client.tsx
│ │ │ │ │ │ │ ├── _layoutComponents/
│ │ │ │ │ │ │ │ ├── NoData/
│ │ │ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ └── SectionHeader/
│ │ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ ├── billing/
│ │ │ │ │ │ │ │ ├── page.module.scss
│ │ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ │ ├── domains/
│ │ │ │ │ │ │ │ ├── AddDomain/
│ │ │ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ ├── ManageDomain/
│ │ │ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ │ └── page_client.tsx
│ │ │ │ │ │ │ ├── email/
│ │ │ │ │ │ │ │ ├── AddEmailDomain/
│ │ │ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ ├── ManageEmailDomain/
│ │ │ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ │ └── page_client.tsx
│ │ │ │ │ │ │ ├── environment-variables/
│ │ │ │ │ │ │ │ ├── AddEnvs/
│ │ │ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ ├── ManageEnvs/
│ │ │ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ ├── Secret/
│ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ ├── page.module.scss
│ │ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ │ └── validations.ts
│ │ │ │ │ │ │ ├── layout.module.scss
│ │ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ │ ├── ownership/
│ │ │ │ │ │ │ │ ├── page.module.scss
│ │ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ │ └── page_client.tsx
│ │ │ │ │ │ │ └── plan/
│ │ │ │ │ │ │ ├── DeletePlanButton/
│ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ ├── DeletePlanModal/
│ │ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── configure/
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ └── env/
│ │ │ │ │ │ └── [environment-slug]/
│ │ │ │ │ │ └── (tabs)/
│ │ │ │ │ │ ├── (overview)/
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── ProjectBillingMessages/
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── database/
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── file-storage/
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ ├── logs/
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ └── settings/
│ │ │ │ │ │ ├── (build-settings)/
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── billing/
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── domains/
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── email/
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── environment-variables/
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ ├── ownership/
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ └── plan/
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── _actions/
│ │ │ │ │ │ └── revalidateCache.ts
│ │ │ │ │ ├── _api/
│ │ │ │ │ │ ├── fetchGitHubToken.ts
│ │ │ │ │ │ ├── fetchInstalls.ts
│ │ │ │ │ │ ├── fetchInvoices.ts
│ │ │ │ │ │ ├── fetchMe.ts
│ │ │ │ │ │ ├── fetchPaymentMethod.ts
│ │ │ │ │ │ ├── fetchPaymentMethods.ts
│ │ │ │ │ │ ├── fetchPlans.ts
│ │ │ │ │ │ ├── fetchProject.ts
│ │ │ │ │ │ ├── fetchProjects.ts
│ │ │ │ │ │ ├── fetchRepos.ts
│ │ │ │ │ │ ├── fetchSubscriptions.ts
│ │ │ │ │ │ ├── fetchTeam.ts
│ │ │ │ │ │ ├── fetchTemplate.ts
│ │ │ │ │ │ ├── fetchTemplates.ts
│ │ │ │ │ │ ├── token.ts
│ │ │ │ │ │ ├── updateCustomer.ts
│ │ │ │ │ │ ├── updatePaymentMethod.ts
│ │ │ │ │ │ └── updateSubscription.ts
│ │ │ │ │ ├── _components/
│ │ │ │ │ │ ├── BranchSelector/
│ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ └── reducer.ts
│ │ │ │ │ │ ├── CloneOrDeployProgress/
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── CloudFooter/
│ │ │ │ │ │ │ ├── classes.module.scss
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── CloudHeader/
│ │ │ │ │ │ │ ├── classes.module.scss
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── CloudLogo/
│ │ │ │ │ │ │ ├── classes.module.scss
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── ComparePlans/
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── CreditCardElement/
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── CreditCardList/
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ ├── reducer.ts
│ │ │ │ │ │ │ └── usePaymentMethods.ts
│ │ │ │ │ │ ├── CreditCardSelector/
│ │ │ │ │ │ │ ├── ProjectPaymentMethodSelector.tsx
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ └── useSubscription.ts
│ │ │ │ │ │ ├── DashboardBreadcrumbs/
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── DashboardTabs/
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── InstallationButton/
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── InstallationSelector/
│ │ │ │ │ │ │ ├── components/
│ │ │ │ │ │ │ │ ├── MenuList/
│ │ │ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ ├── Option/
│ │ │ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ └── SingleValue/
│ │ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ ├── types.ts
│ │ │ │ │ │ │ └── useGetInstalls.ts
│ │ │ │ │ │ ├── InviteTeammates/
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── PlanSelector/
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── ProjectCard/
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── ProjectHeader/
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── RadioGroup/
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── RepoExists/
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── Sidebar/
│ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ └── layout.module.scss
│ │ │ │ │ │ ├── Tabs/
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── TeamDrawer/
│ │ │ │ │ │ │ ├── DrawerContent.module.scss
│ │ │ │ │ │ │ ├── DrawerContent.tsx
│ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ └── types.ts
│ │ │ │ │ │ ├── TeamInvitations/
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── TeamMembers/
│ │ │ │ │ │ │ ├── TeamMemberRow.module.scss
│ │ │ │ │ │ │ ├── TeamMemberRow.tsx
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── TeamSelector/
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── UniqueDomain/
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ └── reducer.ts
│ │ │ │ │ │ ├── UniqueRepoName/
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ └── UniqueSlug/
│ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ └── reducer.ts
│ │ │ │ │ ├── _utilities/
│ │ │ │ │ │ ├── hasBadSubscription.ts
│ │ │ │ │ │ ├── projectHasPaymentMethod.ts
│ │ │ │ │ │ └── teamHasDefaultPaymentMethod.ts
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ ├── not-found.tsx
│ │ │ │ │ └── slug.ts
│ │ │ │ ├── cloud-terms/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── forgot-password/
│ │ │ │ │ ├── page.module.scss
│ │ │ │ │ ├── page.tsx
│ │ │ │ │ └── page_client.tsx
│ │ │ │ ├── join-team/
│ │ │ │ │ ├── page.module.scss
│ │ │ │ │ ├── page.tsx
│ │ │ │ │ └── page_client.tsx
│ │ │ │ ├── layout.module.scss
│ │ │ │ ├── layout.tsx
│ │ │ │ ├── login/
│ │ │ │ │ ├── page.module.scss
│ │ │ │ │ ├── page.tsx
│ │ │ │ │ └── page_client.tsx
│ │ │ │ ├── logout/
│ │ │ │ │ ├── page.module.scss
│ │ │ │ │ ├── page.tsx
│ │ │ │ │ └── page_client.tsx
│ │ │ │ ├── new/
│ │ │ │ │ ├── (checkout)/
│ │ │ │ │ │ ├── Checkout.module.scss
│ │ │ │ │ │ ├── Checkout.tsx
│ │ │ │ │ │ ├── EnvVars.module.scss
│ │ │ │ │ │ ├── EnvVars.tsx
│ │ │ │ │ │ ├── confirmCardPayment.ts
│ │ │ │ │ │ ├── confirmCardSetup.ts
│ │ │ │ │ │ ├── createSetupIntent.ts
│ │ │ │ │ │ ├── createSubscription.ts
│ │ │ │ │ │ ├── deploy.tsx
│ │ │ │ │ │ └── reducer.ts
│ │ │ │ │ ├── authorize/
│ │ │ │ │ │ ├── checkGitHubToken.ts
│ │ │ │ │ │ ├── exchangeCode.ts
│ │ │ │ │ │ ├── page.module.scss
│ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ └── page_client.tsx
│ │ │ │ │ ├── clone/
│ │ │ │ │ │ ├── [template-slug]/
│ │ │ │ │ │ │ ├── page.module.scss
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ └── page_client.tsx
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── createDraftProject.tsx
│ │ │ │ │ ├── import/
│ │ │ │ │ │ ├── RepoCard/
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── page.module.scss
│ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ ├── page_client.tsx
│ │ │ │ │ │ └── useGetRepos.ts
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── reset-password/
│ │ │ │ │ ├── page.module.scss
│ │ │ │ │ ├── page.tsx
│ │ │ │ │ └── page_client.tsx
│ │ │ │ └── verify/
│ │ │ │ └── page.tsx
│ │ │ ├── (pages)/
│ │ │ │ ├── [...slug]/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── case-studies/
│ │ │ │ │ └── [slug]/
│ │ │ │ │ ├── client_page.tsx
│ │ │ │ │ ├── index.module.scss
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── community-help/
│ │ │ │ │ ├── (posts)/
│ │ │ │ │ │ ├── discord/
│ │ │ │ │ │ │ └── [slug]/
│ │ │ │ │ │ │ ├── client_page.tsx
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── github/
│ │ │ │ │ │ │ └── [slug]/
│ │ │ │ │ │ │ ├── client_page.tsx
│ │ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ └── layout.tsx
│ │ │ │ │ ├── AlgoliaProvider/
│ │ │ │ │ │ ├── getInitialState.ts
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── ArchiveSearchBar/
│ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── client_page.tsx
│ │ │ │ │ ├── index.module.scss
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── cookie/
│ │ │ │ │ ├── client_page.tsx
│ │ │ │ │ ├── index.module.scss
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── docs/
│ │ │ │ │ ├── [topic]/
│ │ │ │ │ │ └── [doc]/
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── dynamic/
│ │ │ │ │ │ └── [topic]/
│ │ │ │ │ │ └── [doc]/
│ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── fetchTopicsForSidebar.ts
│ │ │ │ │ ├── local/
│ │ │ │ │ │ └── [topic]/
│ │ │ │ │ │ └── [doc]/
│ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ └── v2/
│ │ │ │ │ └── [topic]/
│ │ │ │ │ └── [doc]/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── layout.tsx
│ │ │ │ ├── page.tsx
│ │ │ │ ├── partners/
│ │ │ │ │ ├── [slug]/
│ │ │ │ │ │ ├── index.module.scss
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── index.module.scss
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── posts/
│ │ │ │ │ └── [category]/
│ │ │ │ │ ├── [slug]/
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── index.module.scss
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── privacy/
│ │ │ │ │ ├── page.module.scss
│ │ │ │ │ ├── page.tsx
│ │ │ │ │ └── page_client.tsx
│ │ │ │ ├── styleguide/
│ │ │ │ │ ├── PageContent/
│ │ │ │ │ │ ├── Breadcrumbs/
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── RenderDarkMode/
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── blocks/
│ │ │ │ │ │ ├── banner-block/
│ │ │ │ │ │ │ ├── client_page.tsx
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── call-to-action/
│ │ │ │ │ │ │ ├── client_page.tsx
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── card-grid/
│ │ │ │ │ │ │ ├── client_page.tsx
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── content-grid/
│ │ │ │ │ │ │ ├── client_page.tsx
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── form-block/
│ │ │ │ │ │ │ ├── client_page.tsx
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── hover-highlights/
│ │ │ │ │ │ │ ├── client_page.tsx
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ ├── link-grid/
│ │ │ │ │ │ │ ├── client_page.tsx
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ └── media-content/
│ │ │ │ │ │ ├── client_page.tsx
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── buttons/
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── cards/
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── fields/
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── forms/
│ │ │ │ │ │ ├── client_page.tsx
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── heros/
│ │ │ │ │ │ └── form-hero/
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── highlight/
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── icons/
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── layout.module.scss
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ ├── page.tsx
│ │ │ │ │ └── typography/
│ │ │ │ │ └── page.tsx
│ │ │ │ └── thanks-for-subscribing/
│ │ │ │ ├── client_page.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── api/
│ │ │ │ ├── exit-preview/
│ │ │ │ │ └── route.ts
│ │ │ │ ├── locate/
│ │ │ │ │ └── route.ts
│ │ │ │ ├── og/
│ │ │ │ │ └── route.tsx
│ │ │ │ ├── preview/
│ │ │ │ │ └── route.ts
│ │ │ │ ├── revalidate/
│ │ │ │ │ └── route.ts
│ │ │ │ ├── star-count/
│ │ │ │ │ └── route.ts
│ │ │ │ ├── sync-algolia/
│ │ │ │ │ └── route.ts
│ │ │ │ └── sync-ch/
│ │ │ │ └── route.ts
│ │ │ ├── error.tsx
│ │ │ ├── fonts.ts
│ │ │ ├── gh/
│ │ │ │ └── page.tsx
│ │ │ ├── layout.tsx
│ │ │ ├── not-found.tsx
│ │ │ └── types.ts
│ │ ├── (payload)/
│ │ │ ├── admin/
│ │ │ │ ├── [[...segments]]/
│ │ │ │ │ ├── not-found.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ └── importMap.js
│ │ │ ├── api/
│ │ │ │ ├── [...slug]/
│ │ │ │ │ └── route.ts
│ │ │ │ ├── graphql/
│ │ │ │ │ └── route.ts
│ │ │ │ └── graphql-playground/
│ │ │ │ └── route.ts
│ │ │ ├── custom.scss
│ │ │ └── layout.tsx
│ │ ├── _data/
│ │ │ ├── index.ts
│ │ │ ├── me.ts
│ │ │ ├── plans.ts
│ │ │ ├── project.ts
│ │ │ ├── team.ts
│ │ │ ├── templates.ts
│ │ │ └── token.ts
│ │ ├── api/
│ │ │ └── analytics/
│ │ │ ├── active-users/
│ │ │ │ ├── route.d.ts
│ │ │ │ └── route.js
│ │ │ ├── channel-groups/
│ │ │ │ ├── route.d.ts
│ │ │ │ └── route.js
│ │ │ ├── mockData.d.ts
│ │ │ ├── mockData.js
│ │ │ └── pageviews/
│ │ │ ├── route.d.ts
│ │ │ └── route.js
│ │ └── global-error.tsx
│ ├── blocks/
│ │ ├── Banner/
│ │ │ └── index.ts
│ │ ├── BlogContent/
│ │ │ └── index.ts
│ │ ├── BlogMarkdown/
│ │ │ ├── Field/
│ │ │ │ ├── index.scss
│ │ │ │ ├── index.tsx
│ │ │ │ └── validate.ts
│ │ │ └── index.ts
│ │ ├── CallToAction/
│ │ │ └── index.ts
│ │ ├── Callout/
│ │ │ └── index.ts
│ │ ├── CardGrid/
│ │ │ └── index.ts
│ │ ├── CaseStudiesHighlight/
│ │ │ └── index.ts
│ │ ├── CaseStudyCards/
│ │ │ └── index.ts
│ │ ├── CaseStudyParallax/
│ │ │ └── index.ts
│ │ ├── Code/
│ │ │ └── index.ts
│ │ ├── CodeFeature/
│ │ │ └── index.ts
│ │ ├── ComparisonTable/
│ │ │ └── index.ts
│ │ ├── Content/
│ │ │ └── index.ts
│ │ ├── ContentGrid/
│ │ │ └── index.ts
│ │ ├── Download/
│ │ │ └── index.ts
│ │ ├── ExampleTabs/
│ │ │ └── index.ts
│ │ ├── Form/
│ │ │ └── index.ts
│ │ ├── HoverCards/
│ │ │ └── index.ts
│ │ ├── HoverHighlights/
│ │ │ └── index.ts
│ │ ├── LinkGrid/
│ │ │ └── index.ts
│ │ ├── LogoGrid/
│ │ │ └── index.ts
│ │ ├── Media/
│ │ │ └── index.ts
│ │ ├── MediaContent/
│ │ │ └── index.ts
│ │ ├── MediaContentAccordion/
│ │ │ └── index.ts
│ │ ├── Pricing/
│ │ │ └── index.ts
│ │ ├── ReusableContent/
│ │ │ └── index.ts
│ │ ├── Slider/
│ │ │ └── index.ts
│ │ ├── Statement/
│ │ │ └── index.ts
│ │ ├── Steps/
│ │ │ └── index.ts
│ │ └── StickyHighlights/
│ │ └── index.ts
│ ├── collections/
│ │ ├── CaseStudies.ts
│ │ ├── Categories.ts
│ │ ├── CommunityHelp/
│ │ │ ├── extract-description.ts
│ │ │ ├── index.ts
│ │ │ └── updateAlgolia.ts
│ │ ├── Docs/
│ │ │ ├── BranchButton/
│ │ │ │ ├── fetchAllBranches.ts
│ │ │ │ ├── index.client.tsx
│ │ │ │ ├── index.scss
│ │ │ │ └── index.tsx
│ │ │ ├── SaveButton/
│ │ │ │ ├── index.scss
│ │ │ │ └── index.tsx
│ │ │ ├── blocks/
│ │ │ │ ├── VideoDrawer/
│ │ │ │ │ └── index.ts
│ │ │ │ ├── arrow/
│ │ │ │ │ └── index.ts
│ │ │ │ ├── banner/
│ │ │ │ │ └── index.ts
│ │ │ │ ├── bulletList/
│ │ │ │ │ └── index.ts
│ │ │ │ ├── code/
│ │ │ │ │ ├── CodeFields.tsx
│ │ │ │ │ ├── converter.ts
│ │ │ │ │ ├── converterClient.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── lightDarkImage/
│ │ │ │ │ └── index.ts
│ │ │ │ ├── payloadMedia/
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── pill/
│ │ │ │ │ └── index.ts
│ │ │ │ ├── resource/
│ │ │ │ │ └── index.ts
│ │ │ │ ├── restExamples/
│ │ │ │ │ └── index.ts
│ │ │ │ ├── shared.ts
│ │ │ │ ├── tableWithDrawers/
│ │ │ │ │ └── index.ts
│ │ │ │ ├── upload/
│ │ │ │ │ └── index.ts
│ │ │ │ └── youtube/
│ │ │ │ └── index.ts
│ │ │ ├── index.ts
│ │ │ ├── mdxToLexical.ts
│ │ │ ├── topicOrder.ts
│ │ │ └── types.ts
│ │ ├── Media.ts
│ │ ├── Pages.ts
│ │ ├── PartnerFilters.ts
│ │ ├── Partners.ts
│ │ ├── Posts.ts
│ │ ├── ReusableContent.ts
│ │ └── Users.ts
│ ├── components/
│ │ ├── Accordion/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── AfterNavActions/
│ │ │ ├── index.scss
│ │ │ └── index.tsx
│ │ ├── Analytics/
│ │ │ ├── GoogleAnalytics/
│ │ │ │ └── index.tsx
│ │ │ └── GoogleTagManager/
│ │ │ └── index.tsx
│ │ ├── Archive/
│ │ │ ├── MobileNav/
│ │ │ │ └── index.tsx
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── AuthorTag/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── Avatar/
│ │ │ ├── DropdownMenu/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── BackButton/
│ │ │ └── index.tsx
│ │ ├── BackgroundGradient/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── BackgroundGrid/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── BackgroundScanline/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── Banner/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── BigThree/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── BlockSpacing/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── BlockWrapper/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── BorderBox/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── Breadcrumbs/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── Button/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── CMSForm/
│ │ │ ├── Label/
│ │ │ │ ├── index.module.scss
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ ├── Submit/
│ │ │ │ └── index.tsx
│ │ │ ├── Width/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── fields/
│ │ │ │ ├── Checkbox/
│ │ │ │ │ ├── index.module.scss
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── Select/
│ │ │ │ │ ├── countries.ts
│ │ │ │ │ ├── index.module.scss
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── states.ts
│ │ │ │ ├── Text/
│ │ │ │ │ ├── index.module.scss
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── Textarea/
│ │ │ │ │ ├── index.module.scss
│ │ │ │ │ └── index.tsx
│ │ │ │ └── shared.scss
│ │ │ ├── fields.module.scss
│ │ │ ├── fields.tsx
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── CMSLink/
│ │ │ └── index.tsx
│ │ ├── ChangeHeaderTheme/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── CircleIconButton/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── Code/
│ │ │ ├── index.module.scss
│ │ │ ├── index.tsx
│ │ │ ├── theme.ts
│ │ │ └── types.ts
│ │ ├── CodeBlip/
│ │ │ ├── Button/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── CodeBlipContext.tsx
│ │ │ ├── Modal/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ └── index.tsx
│ │ ├── CommandLine/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── ContributionTable/
│ │ │ ├── api.ts
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── CopyToClipboard/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── CreatePayloadApp/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── DiscordGitBody/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── DiscordGitCTA/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── DiscordGitComments/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── DiscordGitIntro/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── DiscordUsersPill/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── DocsNavigation/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── Drawer/
│ │ │ ├── index.module.scss
│ │ │ ├── index.tsx
│ │ │ ├── types.ts
│ │ │ └── useDrawerSlug.tsx
│ │ ├── DropdownMenu/
│ │ │ ├── MenuContent/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── EdgeScroll/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── ErrorMessage/
│ │ │ └── index.tsx
│ │ ├── ExtendedBackground/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── FeaturedBlogPost/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── Feedback/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── FileAttachment/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── Footer/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── GithubStarsPill/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── GuestSocials/
│ │ │ └── index.tsx
│ │ ├── Gutter/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── HR/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── Header/
│ │ │ ├── DesktopNav/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Docsearch/
│ │ │ │ ├── Component.tsx
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── MobileNav/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── Heading/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── Hero/
│ │ │ ├── BreadcrumbsBar/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── CenteredContent/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── ContentMedia/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Default/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── FormHero/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Gradient/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Home/
│ │ │ │ ├── LogoShowcase/
│ │ │ │ │ ├── index.module.scss
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── HomeNew/
│ │ │ │ ├── LogoShowcase/
│ │ │ │ │ ├── index.module.scss
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Livestream/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Three/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── index.tsx
│ │ │ └── useGetHeroPadding.ts
│ │ ├── Highlight/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── Indicator/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── Label/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── LargeBody/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── LargeRadio/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── LineDraw/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── LoadingShimmer/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── MDX/
│ │ │ └── components/
│ │ │ ├── Table/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ └── TableWithDrawers/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── MaxWidth/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── Media/
│ │ │ ├── Image/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Video/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ │ ├── MediaParallax/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── MediaStack/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── Message/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── ModalWindow/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── NewProject/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── NewsletterSignUp/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── OpenPost/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── Pagination/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── PartnerDirectory/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── PartnerGrid/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── Payload3D/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── PayloadRedirects/
│ │ │ └── index.tsx
│ │ ├── Pill/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── PixelBackground/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── Post/
│ │ │ ├── AuthorsList/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── PrivacyBanner/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── RedeployButton/
│ │ │ ├── index.scss
│ │ │ └── index.tsx
│ │ ├── RefreshMdxToLexicalButton/
│ │ │ ├── index.scss
│ │ │ └── index.tsx
│ │ ├── RefreshRouterOnSave/
│ │ │ └── index.tsx
│ │ ├── RelatedHelpList/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── RelatedResources/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── RenderBlocks/
│ │ │ ├── index.tsx
│ │ │ └── utilities.ts
│ │ ├── RenderDocs/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── RenderParams/
│ │ │ ├── Component.tsx
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── RichText/
│ │ │ ├── Arrow/
│ │ │ │ ├── index.scss
│ │ │ │ └── index.tsx
│ │ │ ├── BulletList/
│ │ │ │ ├── index.scss
│ │ │ │ └── index.tsx
│ │ │ ├── CustomTable/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Heading/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── LightDarkImage/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── PayloadMedia/
│ │ │ │ └── index.tsx
│ │ │ ├── Pill/
│ │ │ │ ├── index.scss
│ │ │ │ └── index.tsx
│ │ │ ├── ResourceBlock/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── RestExamples/
│ │ │ │ ├── generateRequest.tsx
│ │ │ │ ├── generateResponse.tsx
│ │ │ │ ├── index.module.scss
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ ├── Table/
│ │ │ │ └── index.tsx
│ │ │ ├── TableWithDrawers/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Upload/
│ │ │ │ └── index.tsx
│ │ │ ├── UploadBlock/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Video/
│ │ │ │ ├── Vimeo/
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── YouTube/
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── VideoDrawer/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── context.tsx
│ │ │ ├── formatAnchor.ts
│ │ │ ├── index.scss
│ │ │ └── index.tsx
│ │ ├── SimpleLogs/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── SocialIcon/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── Spinner/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── SplitAnimate/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── SpotlightAnimation/
│ │ │ ├── index.module.scss
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ │ ├── SyncCommunityHelp/
│ │ │ ├── index.scss
│ │ │ └── index.tsx
│ │ ├── SyncDocsButton/
│ │ │ ├── index.scss
│ │ │ └── index.tsx
│ │ ├── SyncToAlgolia/
│ │ │ ├── index.scss
│ │ │ └── index.tsx
│ │ ├── TableCheckboxField/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── TableOfContents/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── TemplateCardsBlock/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── Tooltip/
│ │ │ ├── TooltipContent/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── TopBar/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── UniversalTruth/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── VersionSelector/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── YouTube/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── blocks/
│ │ │ ├── Banner/
│ │ │ │ └── index.tsx
│ │ │ ├── BlogContent/
│ │ │ │ └── index.tsx
│ │ │ ├── BlogMarkdown/
│ │ │ │ ├── Block.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── CallToAction/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Callout/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── CardGrid/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── CaseStudiesHighlight/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── CaseStudyCards/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── CaseStudyParallax/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── CodeBlock/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── CodeFeature/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── ComparisonTable/
│ │ │ │ ├── Icons/
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Content/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── ContentGrid/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Download/
│ │ │ │ ├── Buttons/
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── FormBlock/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── HoverCards/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── HoverHighlights/
│ │ │ │ ├── Highlights/
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── LinkGrid/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── LogoGrid/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── MediaBlock/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── MediaContent/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── MediaContentAccordion/
│ │ │ │ ├── Desktop/
│ │ │ │ │ ├── index.module.scss
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── Mobile/
│ │ │ │ │ ├── index.module.scss
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Pricing/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── RelatedPosts/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── ReusableContent/
│ │ │ │ └── index.tsx
│ │ │ ├── Slider/
│ │ │ │ ├── QuoteCard/
│ │ │ │ │ ├── index.module.scss
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Statement/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Steps/
│ │ │ │ ├── Step/
│ │ │ │ │ ├── index.module.scss
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ └── StickyHighlights/
│ │ │ ├── Highlight/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ └── cards/
│ │ ├── ContentMediaCard/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── DefaultCard/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── PartnerCard/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── PricingCard/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── SquareCard/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ └── types.ts
│ ├── constants.ts
│ ├── css/
│ │ ├── app.scss
│ │ ├── colors.scss
│ │ ├── common.scss
│ │ ├── docsearch.scss
│ │ ├── github.scss
│ │ ├── grid.scss
│ │ ├── queries.scss
│ │ ├── theme.scss
│ │ ├── toasts.scss
│ │ ├── type.scss
│ │ └── vars.scss
│ ├── fields/
│ │ ├── addToDocs/
│ │ │ ├── Label.tsx
│ │ │ ├── index.module.scss
│ │ │ └── index.ts
│ │ ├── blockFields.ts
│ │ ├── codeBlips.ts
│ │ ├── fullTitle/
│ │ │ ├── index.ts
│ │ │ └── populateFullTitle.ts
│ │ ├── hero.ts
│ │ ├── link.ts
│ │ ├── linkGroup.ts
│ │ ├── livestreamFields.ts
│ │ ├── richText/
│ │ │ ├── features/
│ │ │ │ ├── label/
│ │ │ │ │ ├── LabelNode.ts
│ │ │ │ │ ├── client/
│ │ │ │ │ │ ├── icon/
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ └── styles.scss
│ │ │ │ │ └── server/
│ │ │ │ │ └── index.ts
│ │ │ │ └── largeBody/
│ │ │ │ ├── LargeBodyNode.ts
│ │ │ │ ├── client/
│ │ │ │ │ ├── icon/
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── styles.scss
│ │ │ │ └── server/
│ │ │ │ └── index.ts
│ │ │ └── index.ts
│ │ └── slug.ts
│ ├── forms/
│ │ ├── Error/
│ │ │ ├── index.module.scss
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ │ ├── Form/
│ │ │ ├── context.ts
│ │ │ ├── index.tsx
│ │ │ ├── initialContext.ts
│ │ │ ├── reduceFieldsToValues.ts
│ │ │ └── reducer.ts
│ │ ├── FormProcessing/
│ │ │ └── index.tsx
│ │ ├── FormSubmissionError/
│ │ │ └── index.tsx
│ │ ├── Label/
│ │ │ ├── index.module.scss
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ │ ├── Submit/
│ │ │ └── index.tsx
│ │ ├── fields/
│ │ │ ├── Array/
│ │ │ │ ├── context.tsx
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Checkbox/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Number/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── RadioGroup/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Secret/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Select/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Text/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Textarea/
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── shared.scss
│ │ │ ├── types.ts
│ │ │ └── useField/
│ │ │ └── index.tsx
│ │ ├── types.ts
│ │ ├── useFormField/
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ │ └── validations.ts
│ ├── globals/
│ │ ├── CustomRowLabelNavItems.tsx
│ │ ├── CustomRowLabelTabs.tsx
│ │ ├── Footer.ts
│ │ ├── GetStarted.ts
│ │ ├── MainMenu.ts
│ │ ├── PartnerProgram.ts
│ │ └── TopBar.ts
│ ├── graphics/
│ │ ├── CalendarIcon/
│ │ │ └── index.tsx
│ │ ├── ChevronIcon/
│ │ │ └── index.tsx
│ │ ├── ClockIcon/
│ │ │ └── index.tsx
│ │ ├── CommentsIcon/
│ │ │ └── index.tsx
│ │ ├── CommitIcon/
│ │ │ └── index.tsx
│ │ ├── DiscordIcon/
│ │ │ └── index.tsx
│ │ ├── DownloadIcon/
│ │ │ └── index.tsx
│ │ ├── FacebookIcon/
│ │ │ └── index.tsx
│ │ ├── FilterIcon/
│ │ │ └── index.tsx
│ │ ├── FullLogo/
│ │ │ └── index.tsx
│ │ ├── GitHub/
│ │ │ └── index.tsx
│ │ ├── GithubIcon/
│ │ │ └── index.tsx
│ │ ├── InfoIcon/
│ │ │ └── index.tsx
│ │ ├── InstagramIcon/
│ │ │ └── index.tsx
│ │ ├── MenuIcon/
│ │ │ └── index.tsx
│ │ ├── PayloadIcon/
│ │ │ └── index.tsx
│ │ ├── SearchIcon/
│ │ │ └── index.tsx
│ │ ├── SearchIconV2/
│ │ │ └── index.tsx
│ │ ├── ThemeAutoIcon/
│ │ │ └── index.tsx
│ │ ├── ThemeDarkIcon/
│ │ │ └── index.tsx
│ │ ├── ThemeLightIcon/
│ │ │ └── index.tsx
│ │ ├── TwitterIcon/
│ │ │ └── index.tsx
│ │ ├── TwitterIconAlt/
│ │ │ └── index.tsx
│ │ ├── TwitterIconV2/
│ │ │ └── index.tsx
│ │ └── YoutubeIcon/
│ │ └── index.tsx
│ ├── hooks/
│ │ ├── revalidateRedirects.ts
│ │ └── usePopulateDocument.ts
│ ├── icons/
│ │ ├── ArrowIcon/
│ │ │ └── index.tsx
│ │ ├── ArrowRightIcon/
│ │ │ └── index.tsx
│ │ ├── BranchIcon/
│ │ │ └── index.tsx
│ │ ├── ChainLinkIcon/
│ │ │ └── index.tsx
│ │ ├── CheckIcon/
│ │ │ └── index.tsx
│ │ ├── ChevronDownIcon/
│ │ │ └── index.tsx
│ │ ├── ChevronIcon/
│ │ │ └── index.tsx
│ │ ├── ChevronUpDownIcon/
│ │ │ └── index.tsx
│ │ ├── CloseIcon/
│ │ │ └── index.tsx
│ │ ├── CodeIcon/
│ │ │ └── index.tsx
│ │ ├── Copy/
│ │ │ └── index.tsx
│ │ ├── CopyIcon/
│ │ │ └── index.tsx
│ │ ├── CrosshairIcon/
│ │ │ └── index.tsx
│ │ ├── ErrorIcon/
│ │ │ └── index.tsx
│ │ ├── ExternalLinkIcon/
│ │ │ └── index.tsx
│ │ ├── EyeIcon/
│ │ │ └── index.tsx
│ │ ├── FolderIcon/
│ │ │ └── index.tsx
│ │ ├── GradientBorderIcon/
│ │ │ └── index.tsx
│ │ ├── InfoIcon/
│ │ │ └── index.tsx
│ │ ├── LoaderIcon/
│ │ │ └── index.tsx
│ │ ├── PlayIcon/
│ │ │ └── index.tsx
│ │ ├── PlusIcon/
│ │ │ └── index.tsx
│ │ ├── QuoteIcon/
│ │ │ └── index.tsx
│ │ ├── QuoteIconAlt/
│ │ │ └── index.tsx
│ │ ├── SearchIcon/
│ │ │ └── index.tsx
│ │ ├── TrashIcon/
│ │ │ └── index.tsx
│ │ ├── index.module.scss
│ │ └── types.ts
│ ├── migrate.ts
│ ├── migrations/
│ │ ├── 20241116_194708_migration.ts
│ │ └── index.ts
│ ├── payload-cloud-types.ts
│ ├── payload-types.ts
│ ├── payload.config.ts
│ ├── plugins/
│ │ └── opsCounter.ts
│ ├── providers/
│ │ ├── Auth/
│ │ │ └── index.tsx
│ │ ├── ComputedCSSValues/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── HeaderIntersectionObserver/
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── PageTransition/
│ │ │ └── index.tsx
│ │ ├── Privacy/
│ │ │ └── index.tsx
│ │ ├── Theme/
│ │ │ ├── index.tsx
│ │ │ ├── shared.ts
│ │ │ └── types.ts
│ │ ├── ToastContainer/
│ │ │ ├── icons/
│ │ │ │ ├── Error.tsx
│ │ │ │ ├── Info.tsx
│ │ │ │ ├── Success.tsx
│ │ │ │ └── Warning.tsx
│ │ │ └── index.tsx
│ │ └── index.tsx
│ ├── scripts/
│ │ ├── clearDuplicateThreads.ts
│ │ ├── fetchDiscord.ts
│ │ ├── fetchDocs.ts
│ │ ├── fetchGitHub.ts
│ │ ├── generateLLMs.ts
│ │ ├── migrateAuthors.js
│ │ ├── migrateVersions.ts
│ │ ├── redeployWebsite.ts
│ │ ├── syncDocs.ts
│ │ └── syncToAlgolia.ts
│ ├── seo/
│ │ └── mergeOpenGraph.ts
│ ├── ts-helpers/
│ │ └── requireField.ts
│ └── utilities/
│ ├── analytics.ts
│ ├── can-use-dom.ts
│ ├── check-team-roles.ts
│ ├── decode-base-64.ts
│ ├── deepMerge.ts
│ ├── format-date-time.ts
│ ├── formatPagePath.ts
│ ├── formatPermalink.js
│ ├── formatPreviewURL.ts
│ ├── formatSlug.ts
│ ├── generate-route-path.ts
│ ├── get-cookie.ts
│ ├── get-relative-date.ts
│ ├── get-specific-date-time.ts
│ ├── get-team-twitter.ts
│ ├── get-video.ts
│ ├── getDocument.ts
│ ├── getRedirects.ts
│ ├── getSafeRedirect.ts
│ ├── is-expanded-doc.ts
│ ├── isNumber.ts
│ ├── isValidParamID.ts
│ ├── merge-project-environment.ts
│ ├── oxford-comma.ts
│ ├── parseCookies.ts
│ ├── price-from-json.ts
│ ├── qs.ts
│ ├── revalidate.ts
│ ├── revalidatePage.ts
│ ├── sanitizeSlug.ts
│ ├── slug-to-text.ts
│ ├── slugify.ts
│ ├── to-kebab-case.ts
│ ├── use-click-away.ts
│ ├── use-cloud-api.ts
│ ├── use-debounce.ts
│ ├── use-is-mounted.tsx
│ ├── use-pathname-segments.ts
│ ├── use-popup-window.ts
│ ├── use-resize.ts
│ ├── use-star-count.ts
│ ├── use-websocket.tsx
│ ├── useIntersection.ts
│ └── uuid.ts
├── tsconfig.json
└── vercel.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/on-payload-release.yml
================================================
name: on-payload-release
on:
workflow_dispatch:
repository_dispatch:
types: [payload-release-event]
jobs:
receive-repository-dispatch:
runs-on: ubuntu-latest
# Just log that we received the event
steps:
- name: Log the event payload
if: ${{ github.event_name != 'workflow_dispatch' }}
run: 'echo "Event received: ${{ toJson(github.event.client_payload) }}"'
- name: Slack notification to sync docs
uses: slackapi/slack-github-action@v2.1.1
with:
webhook: ${{ secrets.SLACK_WEBHOOK_WEBSITE_CHANNEL }}
webhook-type: incoming-webhook
payload: |
{
"text": "👀 New version of Payload released. Please sync the docs in the Payload CMS Admin."
}
================================================
FILE: .gitignore
================================================
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
/src/docs
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# local env files
.env*.local
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
.env
# Sentry Config File
.sentryclirc
/.idea/*
!/.idea/runConfigurations
!/.idea/payload.iml
/db/*
================================================
FILE: .prettierignore
================================================
.tmp
**/.git
**/.hg
**/.pnp.*
**/.svn
**/.yarn/**
**/build
**/dist/**
**/node_modules
**/temp
tsconfig.json
payload-types.ts
tsconfig.tsbuildinfo
================================================
FILE: .prettierrc.json
================================================
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"semi": false
}
================================================
FILE: .vscode/extensions.json
================================================
{
"recommendations": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"]
}
================================================
FILE: .vscode/settings.json
================================================
{
"npm.packageManager": "pnpm",
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
}
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
}
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
}
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
},
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
},
"editor.formatOnSaveMode": "file",
"typescript.tsdk": "node_modules/typescript/lib",
"[javascript][typescript][typescriptreact]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
}
}
}
================================================
FILE: Caddyfile
================================================
# Spin up the caddy server with `caddy run` or `yarn caddy`
# this is useful to test the github oauth flow locally
payloadcms.localhost {
reverse_proxy :3000
}
cms.payloadcms.localhost {
reverse_proxy :8001
}
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2023 Payload
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# Payload Website
This is the repository for [Payload's official website](https://payloadcms.com/). It was built completely in public using Payload itself, [more on that here](#⭐-the-cms).
<img src="https://payloadcms.com/images/og-image.jpg" alt="Payload headless CMS website" />
This site showcases lots of cool stuff like how to use Next.js 15 + Payload's local API to its fullest extent, how to build a super dynamic light / dark mode into a Next site without any first-load flickering, how to render remotely stored docs from MDX to Next.js pages using just Payload (no external libraries), how to use Stripe to build a custom SaaS integration, and much more.
## ✨ Tech stack
- [Payload](https://github.com/payloadcms/payload) (obviously)
- TypeScript
- Next.js 15 and its new App Router
- SCSS Modules
- MDX for docs, using the [Lexical MDX Converter](https://payloadcms.com/docs/rich-text/converting-markdown#converting-mdx)
- GraphQL for Payload Cloud
- Stripe for Payload Cloud
## ⭐ The CMS
[Payload](https://github.com/payloadcms/payload) is leveraged for everything that this site does, outside of its documentation which is all stored as Markdown in the Payload repo on GitHub. Both the CMS and the website frontend are found within the same app folder.
## ☁️ Payload Cloud
This repo contains the source code for [Payload Cloud](https://payloadcms.com/cloud-pricing). This is a one-click integration to deploy production-ready instances of your Payload apps directly from your GitHub repo, [read the blog post](https://payloadcms.com/blog/launch-week-day-1-payload-cloud-is-here) to get all the details. The entire frontend of Payload Cloud has been built in public and is included within this repo 😱.
## 🚀 Running the project locally
To get started with this repo locally, follow the steps below:
- Clone the repo
- `pnpm i`
- Run `cp .env.example .env` to create an `.env` file
- Fill out the values within your new `.env`, corresponding to your own environment
- Run `pnpm dev`
- Bam
### Hosts file
The locally running app must run on `local.payloadcms.com:3000` because of http-only cookie policies and how the GitHub App redirects the user back to the site after authenticating. To do this, you'll need to add the following to your hosts file:
```env
127.0.0.1 local.payloadcms.com
```
> On Mac you can find the hosts file at `/etc/hosts`. On Windows, it's at `C:\Windows\System32\drivers\etc\hosts`:
### Documentation
The documentation for this site is stored in the [Payload repo](https://github.com/payloadcms/payload) as Markdown files. These are fetched when you press the "Sync Docs" button in the CMS. Pressing that button does the following:
1. Docs are pulled from the Payload repo on GitHub.
2. The docs are converted from MDX to Lexical and stored in the CMS.
3. The frontend docs pages are revalidated.
4. Visiting the docs pages will pull the latest docs from the CMS, and render those lexical nodes to JSX.
#### Working on the docs locally - GitHub
By default, the docs are pulled from the `main` branch of the Payload repo on GitHub. You can **load the docs** for a different branch by opening the /docs/dynamic/ route on the website. This will dynamically load them every time you visit the page, without needing to sync them in the CMS.
Example:
- This pulls from the main branch: https://payloadcms.com/docs/getting-started/concepts
- This pulls from the feat/myfeature branch: https://payloadcms.com/docs/dynamic/getting-started/concepts?branch=feat/myfeature
In order to edit docs for that branch without touching markdown files, you can use the branch selector in the CMS to select the branch you want to work on. After making changes and saving the document, the lexical docs will be converted to MDX and pushed to the selected branch on GitHub.
You will need to set the following environment variables to work with the GitHub sync:
```env
// .env
# For reading from GitHub
GITHUB_ACCESS_TOKEN=ghp_
GITHUB_CLIENT_SECRET=
# For writing to GitHub - you can run the https://github.com/payloadcms/gh-commit repo locally
COMMIT_DOCS_API_URL=
COMMIT_DOCS_API_KEY=
```
#### Working on docs locally - local markdown files
If you have the docs stored locally as markdown files and would like to preview them in the website, you can use the /docs/local/ route in the website. First, you need to set the `DOCS_DIR_V3` environment variable to point to your local `docs` directory.
```env
// .env
DOCS_DIR_V3=/documents/github/payload/docs
```
Then, just open the `/docs/local/` route: http://localhost:3000/docs/local/getting-started/concepts.
Every time you make a change to the markdown files, just reload the page to see the changes reflected. The local MDX files are read, automatically converted to lexical on-the-fly, and rendered in the website. This process will not make any changes to the database.
#### Beta and Legacy environment flags
You can also specify a `beta` version and `legacy` version to render different versions of the docs:
- Set the environment variable `NEXT_PUBLIC_ENABLE_BETA_DOCS` to `true` to enable the beta docs.
- Specify a branch, commit, or tag with `NEXT_PUBLIC_BETA_DOCS_REF`. The default for the beta docs is `beta`.
- Set the environment variable `NEXT_PUBLIC_ENABLE_LEGACY_DOCS` to `true` to enable the legacy docs.
- Specify a branch, commit, or tag with `NEXT_PUBLIC_LEGACY_DOCS_REF`. The default for the legacy docs is `null`, and will fallback to the `main` branch.
### License
The Payload website is available as open source under the terms of the [MIT license](https://github.com/payloadcms/website/blob/main/LICENSE).
================================================
FILE: algolia.d.ts
================================================
// See https://github.com/epicweb-dev/epic-stack/discussions/247
declare module 'react-instantsearch' {
export { usePagination } from './node_modules/react-instantsearch/dist/es/index.js'
export { useSearchBox } from './node_modules/react-instantsearch/dist/es/index.js'
export { useInstantSearch } from './node_modules/react-instantsearch/dist/es/index.js'
export { Configure } from './node_modules/react-instantsearch/dist/es/index.js'
export { InstantSearch } from './node_modules/react-instantsearch/dist/es/index.js'
}
================================================
FILE: cssVariables.cjs
================================================
module.exports = {
breakpoints: {
s: 768,
m: 1024,
l: 1440,
},
}
================================================
FILE: eslint.config.js
================================================
import payloadEsLintConfig from '@payloadcms/eslint-config'
import payloadPlugin from '@payloadcms/eslint-plugin'
export const defaultESLintIgnores = [
'**/.temp',
'**/.*', // ignore all dotfiles
'**/.git',
'**/.hg',
'**/.pnp.*',
'**/.svn',
'**/playwright.config.ts',
'**/jest.config.js',
'**/tsconfig.tsbuildinfo',
'**/README.md',
'**/eslint.config.js',
'**/payload-types.ts',
'**/dist/',
'**/.yarn/',
'**/build/',
'**/node_modules/',
'**/temp/',
]
/** @typedef {import('eslint').Linter.Config} Config */
export const rootParserOptions = {
sourceType: 'module',
ecmaVersion: 'latest',
projectService: {
maximumDefaultProjectFileMatchCount_THIS_WILL_SLOW_DOWN_LINTING: 40,
allowDefaultProject: ['scripts/*.ts', 'scripts/*.js', '*.js', '*.mjs', '*.spec.ts', '*.d.ts'],
},
}
/** @type {Config[]} */
export const rootEslintConfig = [
...payloadEsLintConfig,
{
ignores: [...defaultESLintIgnores, 'packages/**/*.spec.ts'],
},
{
plugins: {
payload: payloadPlugin,
},
rules: {
'payload/no-jsx-import-statements': 'warn',
restrictDefaultExports: 'off',
},
},
]
const config = [
...rootEslintConfig,
{
languageOptions: {
parserOptions: {
...rootParserOptions,
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
},
{
name: 'Next.js pages',
rules: {
'no-restricted-exports': 'off',
},
files: [
'src/app/**/page.tsx',
'src/app/**/layout.tsx',
'src/app/**/page.client.tsx',
'src/app/**/not-found.tsx',
'src/payload.config.ts',
],
},
]
export default config
================================================
FILE: next-sitemap.config.cjs
================================================
module.exports = {
siteUrl: process.env.SITEMAP_URL || 'https://payloadcms.com',
generateRobotsTxt: true, // (optional)
// ...other options
}
================================================
FILE: next.config.js
================================================
import { withPayload } from '@payloadcms/next/withPayload'
import path from 'path'
import { fileURLToPath } from 'node:url'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
import { redirects } from './redirects.js'
import bundleAnalyzer from '@next/bundle-analyzer'
const withBundleAnalyzer = bundleAnalyzer({
enabled: process.env.ANALYZE === 'true',
})
const localhost = process.env.NEXT_PUBLIC_IS_LIVE
? []
: [
{
protocol: 'http',
hostname: 'localhost',
port: '3000',
},
{
protocol: 'http',
hostname: 'local.payloadcms.com',
port: '3000',
},
{
protocol: 'http',
hostname: 'cms.local.payloadcms.com',
port: '8000',
},
{
protocol: 'http',
hostname: 'cms.local.payloadcms.com',
port: '8001',
},
]
const nextConfig = withBundleAnalyzer({
eslint: {
ignoreDuringBuilds: true,
},
reactStrictMode: true,
images: {
minimumCacheTTL: 60 * 60 * 24 * 365, // 1 year,
remotePatterns: [
...localhost,
{
protocol: 'https',
hostname: 'cms.payloadcms.com',
port: '',
},
{
protocol: 'https',
hostname: 'cloud-api.payloadcms.com',
port: '',
},
{
protocol: 'https',
hostname: 'cms.local.payloadcms.com',
port: '',
},
{
protocol: 'https',
hostname: 'stage.cms.payloadcms.com',
port: '',
},
{
protocol: 'https',
hostname: 'cdn.discordapp.com',
port: '',
},
{
protocol: 'https',
hostname: 'avatars.githubusercontent.com',
port: '',
},
{
protocol: 'https',
hostname: 'img.youtube.com',
port: '',
},
{
protocol: 'https',
hostname: process.env.BLOB_STORE_ID,
},
].filter(Boolean),
},
sassOptions: {
silenceDeprecations: ['legacy-js-api', 'import'], // https://github.com/vercel/next.js/issues/71638
},
turbopack: {
resolveAlias: {
'@scss': path.resolve(dirname, './src/css/'),
'@components': path.resolve(dirname, './src/components.js'),
'@cloud': path.resolve(dirname, './src/app/cloud'),
'@forms': path.resolve(dirname, './src/forms'),
'@blocks': path.resolve(dirname, './src/blocks'),
'@providers': path.resolve(dirname, './src/providers'),
'@icons': path.resolve(dirname, './src/icons'),
'@utilities': path.resolve(dirname, './src/utilities'),
'@types': path.resolve(dirname, './payload-types.ts'),
'@graphics': path.resolve(dirname, './src/graphics'),
'@graphql': path.resolve(dirname, './src/graphql'),
},
},
webpack: (config) => {
const configCopy = { ...config }
configCopy.resolve = {
...config.resolve,
extensions: ['.ts', '.tsx', '.js', '.jsx'],
extensionAlias: {
'.js': ['.ts', '.js', '.tsx', '.jsx'],
'.mjs': ['.mts', '.mjs'],
},
alias: {
...config.resolve.alias,
'@scss': path.resolve(dirname, './src/css/'),
'@components': path.resolve(dirname, './src/components.js'),
'@cloud': path.resolve(dirname, './src/app/cloud'),
'@forms': path.resolve(dirname, './src/forms'),
'@blocks': path.resolve(dirname, './src/blocks'),
'@providers': path.resolve(dirname, './src/providers'),
'@icons': path.resolve(dirname, './src/icons'),
'@utilities': path.resolve(dirname, './src/utilities'),
'@types': path.resolve(dirname, './payload-types.ts'),
'@graphics': path.resolve(dirname, './src/graphics'),
'@graphql': path.resolve(dirname, './src/graphql'),
},
}
return configCopy
},
redirects,
async headers() {
const headers = [
{
source: '/(.*)',
headers: [
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN',
},
{
key: 'Content-Security-Policy',
value: "object-src 'none';base-uri 'self';form-action 'self';",
},
],
},
]
if (!process.env.NEXT_PUBLIC_IS_LIVE) {
headers.push({
source: '/(.*)',
headers: [
{
key: 'X-Robots-Tag',
value: 'noindex',
},
],
})
}
return headers
},
})
export default withPayload(nextConfig, { devBundleServerPackages: false })
================================================
FILE: package.json
================================================
{
"name": "payload-website",
"version": "1.0.4",
"private": true,
"type": "module",
"scripts": {
"dev": "cross-env NODE_OPTIONS=--no-deprecation next dev",
"generate:importmap": "cross-env NODE_OPTIONS=--no-deprecation payload generate:importmap",
"generate:types": "cross-env NODE_OPTIONS=--no-deprecation payload generate:types",
"generate:llms": "payload run src/scripts/generateLLMs.ts",
"build": "pnpm generate:llms && pnpm payload migrate && cross-env NODE_OPTIONS=--no-deprecation next build",
"build:skipDocs": "cross-env NODE_OPTIONS=--no-deprecation next build",
"postbuild": "next-sitemap --config ./next-sitemap.config.cjs",
"analyze": "ANALYZE=true next build",
"caddy": "caddy run --config Caddyfile",
"start": "next start",
"lint": "next lint",
"prettier:fix": "prettier --write .",
"migrate-lexical-script": "payload run ./src/migrate.ts"
},
"dependencies": {
"@docsearch/react": "^3.9.0",
"@faceless-ui/collapsibles": "^2.0.0-beta.0",
"@faceless-ui/css-grid": "1.3.0-rc.0",
"@faceless-ui/modal": "3.0.0-beta.2",
"@faceless-ui/mouse-info": "2.0.0-beta.0",
"@faceless-ui/scroll-info": "2.0.0",
"@faceless-ui/slider": "2.0.0-beta.0",
"@faceless-ui/window-info": "3.0.1",
"@payloadcms/db-mongodb": "3.72.0",
"@payloadcms/email-nodemailer": "3.72.0",
"@payloadcms/live-preview-react": "3.72.0",
"@payloadcms/next": "3.72.0",
"@payloadcms/plugin-form-builder": "3.72.0",
"@payloadcms/plugin-nested-docs": "3.72.0",
"@payloadcms/plugin-redirects": "3.72.0",
"@payloadcms/plugin-seo": "3.72.0",
"@payloadcms/richtext-lexical": "3.72.0",
"@payloadcms/storage-vercel-blob": "3.72.0",
"@payloadcms/ui": "3.72.0",
"@radix-ui/react-accordion": "^1.2.1",
"@radix-ui/react-portal": "^1.1.2",
"@radix-ui/react-tabs": "^1.1.1",
"@stripe/react-stripe-js": "^3.1.1",
"@stripe/stripe-js": "^1.47.0",
"@zubricks/plugin-google-analytics": "^1.0.2",
"algoliasearch": "^4.23.3",
"cheerio": "^1.0.0-rc.12",
"cross-env": "7.0.3",
"discord-markdown": "^2.5.1",
"flatley": "^5.2.0",
"framer-motion": "12.0.0-alpha.2",
"geist": "^1.3.1",
"graphql": "16.8.1",
"gray-matter": "^4.0.3",
"instantsearch.js": "^4.72.2",
"next": "15.4.10",
"next-sitemap": "^4.0.6",
"node-cron": "^3.0.3",
"nodemailer-sendgrid": "^1.0.3",
"payload": "3.72.0",
"prism-react-renderer": "^2.3.1",
"qs-esm": "7.0.2",
"react": "19.2.3",
"react-cookie": "^4.1.1",
"react-dom": "19.2.3",
"react-facebook-pixel": "^1.0.4",
"react-google-recaptcha": "^3.1.0",
"react-instantsearch": "^7.15.3",
"react-markdown": "^9.0.1",
"react-select": "5.9.0",
"react-transition-group": "^4.4.5",
"remark-gfm": "^4.0.0",
"sass": "^1.55.0",
"sharp": "0.32.6",
"sonner": "1.7.0",
"stripe": "^11.11.0",
"uuid": "10.0.0"
},
"devDependencies": {
"@next/bundle-analyzer": "15.3.4",
"@octokit/types": "^9.0.0",
"@payloadcms/eslint-config": "3.28.0",
"@payloadcms/eslint-plugin": "3.28.0",
"@types/cli-progress": "^3.11.0",
"@types/node": "22.10.2",
"@types/react": "19.1.8",
"@types/react-dom": "19.1.6",
"@types/react-google-recaptcha": "^2.1.9",
"cli-progress": "^3.11.2",
"discord.js": "^14.7.1",
"dotenv": "^16.4.7",
"eslint": "9.22.0",
"prettier": "3.4.2",
"typescript": "5.7.3"
},
"pnpm": {
"onlyBuiltDependencies": [
"sharp",
"@parcel/watcher",
"esbuild"
]
},
"packageManager": "pnpm@9.15.4+sha512.b2dc20e2fc72b3e18848459b37359a32064663e5627a51e4c74b2c29dd8e8e0491483c3abb40789cfd578bf362fb6ba8261b05f0387d76792ed6e23ea3b1b6a0"
}
================================================
FILE: public/js/theme.js
================================================
console.log('script')
================================================
FILE: public/llms-full.txt
================================================
# Payload Documentation
# What is Payload?
Source: https://payloadcms.com/docs/getting-started/what-is-payload
<YouTube
id="ftohATkHBi0"
title="Introduction to Payload — The open-source Next.js backend"
/>
**Payload is the Next.js fullstack framework.** Write a Payload Config and instantly get:
- A full Admin Panel using React server / client components, matching the shape of your data and completely extensible with your own React components
- Automatic database schema, including direct DB access and ownership, with migrations, transactions, proper indexing, and more
- Instant REST, GraphQL, and straight-to-DB Node.js APIs
- Authentication which can be used in your own apps
- A deeply customizable access control pattern
- File storage and image management tools like cropping / focal point selection
- Live preview - see your frontend render content changes in realtime as you update
- Lots more
### Instant backend superpowers
No matter what you're building, Payload will give you backend superpowers. Your entire Payload config can be installed in one line into any existing Next.js app, and is designed to catapult your development process. Payload takes the most complex and time-consuming parts of any modern web app and makes them simple.
### Open source - deploy anywhere, including Vercel
It's fully open source with an MIT license and you can self-host anywhere that you can run a Node.js app. You can also deploy serverless to hosts like Vercel, right inside your existing Next.js application.
### Code-first and version controlled
In Payload, there are no "click ops" - as in clicking around in an Admin Panel to define your schema. In Payload, everything is done the right way—code-first and version controlled like a proper backend. But once developers define how Payload should work, non-technical users can independently make use of its Admin Panel to manage whatever they need to without having to know code whatsoever.
### Fully extensible
Even in spite of how much you get out of the box, you still have full control over every aspect of your app - be it database, admin UI, or anything else. Every part of Payload has been designed to be extensible and customizable with modern TypeScript / React. And you'll fully understand the code that you write.
## Use Cases
Payload started as a headless Content Management System (CMS), but since, we've seen our community leverage Payload in ways far outside of simply managing pages and blog posts. It's grown into a full-stack TypeScript app framework.
Large enterprises use Payload to power significant internal tools, retailers power their entire storefronts without the need for headless Shopify, and massive amounts of digital assets are stored + managed within Payload. Of course, websites large and small still use Payload for content management as well.
### Headless CMS
The biggest barrier in large web projects cited by marketers is engineering. On the flip side, engineers say the opposite. This is a big problem that has yet to be solved even though we have countless CMS options.
Payload has restored a little love back into the dev / marketer equation with features like Live Preview, redirects, form builders, visual editing, static A/B testing, and more. But even with all this focus on marketing efficiency, we aren't compromising on the developer experience. That way engineers and marketers alike can be proud of the products they build.
If you're building a website and your frontend is on Next.js, then Payload is a no-brainer.
<Banner type="success">
Instead of going out and signing up for a SaaS vendor that makes it so you
have to manage two completely separate concerns, with little to no native
connection back and forth, just install Payload in your existing Next.js repo
and instantly get a full CMS.
</Banner>
Get started with Payload as a CMS using our official Website template:
```
npx create-payload-app@latest -t website
```
### Enterprise Tool
When a large organization starts up a new software initiative, there's a lot of plumbing to take care of.
- Scaffold the data layer with an ORM or an app framework like Ruby on Rails or Laravel
- Implement their SSO provider for authentication
- Design an access control pattern for authorization
- Open up any REST endpoints required or implement GraphQL queries / mutations
- Implement a migrations workflow for the database as it changes over time
- Integrate with other third party solutions by crafting a system of webhooks or similar
And then there's the [Admin Panel](../admin/overview). Most enterprise tools require an admin UI, and building one from scratch can be the most time-consuming aspect of any new enterprise tool. There are off-the-shelf packages for app frameworks like Rails, but often the customization is so involved that using Material UI or similar from scratch might be better.
Then there are no-code admin builders that could be used. However, wiring up access control and the connection to the data layer, with proper version control, makes this a challenging task as well.
That's where Payload comes in. Payload instantly provides all of this out of the box, making complex internal tools extremely simple to both spin up and maintain over time. The only custom code that will need to be written is any custom business logic. That means Payload can expedite timelines, keep budgets low, and allow engineers to focus on their specific requirements rather than complex backend / admin UI plumbing.
Generally, the best place to start for a new enterprise tool is with a blank canvas, where you can define your own functionality:
```
npx create-payload-app@latest -t blank
```
### Headless Commerce
Companies who prioritize UX generally run into frontend constraints with traditional commerce vendors. These companies will then opt for frontend frameworks like Next.js which allow them to fine-tune their user experience as much as possible—promoting conversions, personalizing experiences, and optimizing for SEO.
But the challenge with using something like Next.js for headless commerce is that in order for non-technical users to manage the storefront, you instantly need to pair a headless commerce product with a headless CMS. Then, your editors need to bounce back and forth between different admin UIs for different functionality. The code required to seamlessly glue them together on the frontend becomes overly complex.
Payload can integrate with any payment processor like Stripe and its content authoring capabilities allow it to manage every aspect of a storefront—all in one place.
If you can build your storefront with a single backend, and only offload things like payment processing, the code will be simpler and the editing experience will be significantly streamlined. Manage products, catalogs, page content, media, and more—all in one spot.
### Digital Asset Management
Payload's API-first tagging, sorting, and querying engine lends itself perfectly to all types of content that a CMS might ordinarily store, but these strong fundamentals also make it a formidable Digital Asset Management (DAM) tool as well.
Similarly to the Ecommerce use case above, if an organization uses a CMS for its content but a separate DAM for its digital assets, administrators of both tools will need to juggle completely different services for tasks that are closely related. Two subscriptions will need to be managed, two sets of infrastructure will need to be provisioned, and two admin UIs need to be used / learned.
Payload flattens CMS and DAM into a single tool that makes no compromises on either side. Powerful features like folder-based organization, file versioning, bulk upload, and media access control allow Payload to simultaneously function as a full Digital Asset Management platform as well as a Content Management System at the same time.
[Click here](https://payloadcms.com/use-cases/digital-asset-management) for more information on how to get started with Payload as a DAM.
## Choosing a Framework
Payload is a great choice for applications of all sizes and types, but it might not be the right choice for every project. Here are some guidelines to help you decide if Payload is the right choice for your project.
### When Payload might be for you
- If data ownership and privacy are important to you, and you don't want to allow another proprietary SaaS vendor to host and own your data
- If you're building a Next.js site that needs a CMS
- If you need to re-use your data outside of a SaaS API
- If what you're building has custom business logic requirements outside of a typical headless CMS
- You want to deploy serverless on platforms like Vercel
### When Payload might not be for you
- If you can manage your project fully with code, and don't need an admin UI
- If you are building a website that fits within the limits of a tool like Webflow or Framer
- If you already have a full database and just need to visualize the data somehow
- If you are confident that you won't need code / data ownership at any point in the future
Ready to get started? First, let's review some high-level concepts that are used in Payload.
# Payload Concepts
Source: https://payloadcms.com/docs/getting-started/concepts
Payload is based around a small and intuitive set of high-level concepts. Before starting to work with Payload, it's a good idea to familiarize yourself with these concepts in order to establish a common language and understanding when discussing Payload.
## Config
The Payload Config is central to everything that Payload does. It allows for the deep configuration of your application through a simple and intuitive API. The Payload Config is a fully-typed JavaScript object that can be infinitely extended upon. [More details](../configuration/overview).
## Database
Payload is database agnostic, meaning you can use any type of database behind Payload's familiar APIs through what is known as a Database Adapter. [More details](../database/overview).
## Collections
A Collection is a group of records, called Documents, that all share a common schema. Each Collection is stored in the [Database](../database/overview) based on the [Fields](../fields/overview) that you define. [More details](../configuration/collections).
## Globals
Globals are in many ways similar to [Collections](../configuration/collections), except they correspond to only a single Document. Each Global is stored in the [Database](../database/overview) based on the [Fields](../fields/overview) that you define. [More details](../configuration/globals).
## Fields
Fields are the building blocks of Payload. They define the schema of the Documents that will be stored in the [Database](../database/overview), as well as automatically generate the corresponding UI within the Admin Panel. [More details](../fields/overview).
## Hooks
Hooks allow you to execute your own side effects during specific events of the Document lifecycle, such as before read, after create, etc. [More details](../hooks/overview).
## Authentication
Payload provides a secure, portable way to manage user accounts out of the box. Payload Authentication is designed to be used in both the Admin Panel, as well as your own external applications. [More details](../authentication/overview).
## Access Control
Access Control determines what a user can and cannot do with any given Document, such as read, update, etc., as well as what they can and cannot see within the Admin Panel. [More details](../access-control/overview).
## Admin Panel
Payload dynamically generates a beautiful, fully type-safe interface to manage your users and data. The Admin Panel is a React application built using the Next.js App Router. [More details](../admin/overview).
## Retrieving Data
Everything Payload does (create, read, update, delete, login, logout, etc.) is exposed to you via three APIs:
- [Local API](#local-api) - Extremely fast, direct-to-database access
- [REST API](#rest-api) - Standard HTTP endpoints for querying and mutating data
- [GraphQL](#graphql-api) - A full GraphQL API with a GraphQL Playground
<Banner type="success">
**Note:** All of these APIs share the exact same query language. [More
details](../queries/overview).
</Banner>
### Local API
By far one of the most powerful aspects of Payload is the fact that it gives you direct-to-database access to your data through the [Local API](../local-api/overview). It's _extremely_ fast and does not incur any typical HTTP overhead—you query your database directly in Node.js.
The Local API is written in TypeScript, and so it is strongly typed and extremely nice to use. It works anywhere on the server, including custom Next.js Routes, Payload Hooks, Payload Access Control, and React Server Components.
Here's a quick example of a React Server Component fetching data using the Local API:
```tsx
import React from 'react'
import config from '@payload-config'
import { getPayload } from 'payload'
const MyServerComponent: React.FC = () => {
const payload = await getPayload({ config })
// The `findResult` here will be fully typed as `PaginatedDocs<Page>`,
// where you will have the `docs` that are returned as well as
// information about how many items are returned / are available in total / etc
const findResult = await payload.find({ collection: 'pages' })
return (
<ul>
{findResult.docs.map((page) => {
// Render whatever here!
// The `page` is fully typed as your Pages collection!
})}
</ul>
)
}
```
<Banner type="info">
For more information about the Local API, [click here](../local-api/overview).
</Banner>
### REST API
By default, the Payload [REST API](../rest-api/overview) is mounted automatically for you at the `/api` path of your app.
For example, if you have a Collection called `pages`:
```ts
fetch('https://localhost:3000/api/pages') // highlight-line
.then((res) => res.json())
.then((data) => console.log(data))
```
<Banner type="info">
For more information about the REST API, [click here](../rest-api/overview).
</Banner>
### GraphQL API
Payload automatically exposes GraphQL queries and mutations through a dedicated [GraphQL API](../graphql/overview). By default, the GraphQL route handler is mounted at the `/api/graphql` path of your app. You'll also find a full GraphQL Playground which can be accessible at the `/api/graphql-playground` path of your app.
You can use any GraphQL client with Payload's GraphQL endpoint. Here are a few packages:
- [`graphql-request`](https://www.npmjs.com/package/graphql-request) - a very lightweight GraphQL client
- [`@apollo/client`](https://www.apollographql.com/docs/react/api/core/ApolloClient/) - an industry-standard GraphQL client with lots of nice features
<Banner type="info">
For more information about the GraphQL API, [click here](../graphql/overview).
</Banner>
## Package Structure
Payload is abstracted into a set of dedicated packages to keep the core `payload` package as lightweight as possible. This allows you to only install the parts of Payload based on your unique project requirements.
<Banner type="warning">
**Important:** Version numbers of all official Payload packages are always
published in sync. You should make sure that you always use matching versions
for all official Payload packages.
</Banner>
`payload`
The `payload` package is where core business logic for Payload lives. You can think of Payload as an ORM with superpowers—it contains the logic for all Payload "operations" like `find`, `create`, `update`, and `delete` and exposes a [Local API](../local-api/overview). It executes [Access Control](../access-control/overview), [Hooks](../hooks/overview), [Validation](../fields/overview#validation), and more.
Payload itself is extremely compact, and can be used in any Node environment. As long as you have `payload` installed and you have access to your Payload Config, you can query and mutate your database directly without going through an unnecessary HTTP layer.
Payload also contains all TypeScript definitions, which can be imported from `payload` directly.
Here's how to import some common Payload types:
```ts
import { Config, CollectionConfig, GlobalConfig, Field } from 'payload'
```
`@payloadcms/next`
Whereas Payload itself is responsible for direct database access, and control over Payload business logic, the `@payloadcms/next` package is responsible for the Admin Panel and the entire HTTP layer that Payload exposes, including the [REST API](../rest-api/overview) and [GraphQL API](../graphql/overview).
`@payloadcms/graphql`
All of Payload's GraphQL functionality is abstracted into a separate package. Payload, its Admin UI, and REST API have absolutely no overlap with GraphQL, and you will incur no performance overhead from GraphQL if you are not using it. However, it's installed within the `@payloadcms/next` package so you don't have to install it manually. You do, however, need to have GraphQL installed separately in your `package.json` if you are using GraphQL.
`@payloadcms/ui`
This is the UI library that Payload's Admin Panel uses. All components are exported from this package and can be re-used as you build extensions to the Payload admin UI, or want to use Payload components in your own React apps. Some exports are server components and some are client components.
`@payloadcms/db-postgres`, `@payloadcms/db-vercel-postgres`, `@payloadcms/db-mongodb`, `@payloadcms/db-sqlite`
You can choose which Database Adapter you'd like to use for your project, and no matter which you choose, the entire data layer for Payload is contained within these packages. You can only use one at a time for any given project.
`@payloadcms/richtext-lexical`, `@payloadcms/richtext-slate`
Payload's Rich Text functionality is abstracted into separate packages and if you want to enable Rich Text in your project, you'll need to install one of these packages. We recommend Lexical for all new projects, and this is where Payload will focus its efforts on from this point, but Slate is still supported if you have already built with it.
<Banner type="info">
**Note:** Rich Text is entirely optional and you may not need it for your
project.
</Banner>
# Installation
Source: https://payloadcms.com/docs/getting-started/installation
## Software Requirements
Payload requires the following software:
- Any JavaScript package manager (pnpm, npm, or yarn - pnpm is preferred)
- Node.js version 20.9.0+
- Any [compatible database](../database/overview) (MongoDB, Postgres or SQLite)
<Banner type="warning">
**Important:** Before proceeding any further, please ensure that you have the
above requirements met.
</Banner>
## Quickstart with create-payload-app
To quickly scaffold a new Payload app in the fastest way possible, you can use [create-payload-app](https://npmjs.com/package/create-payload-app). To do so, run the following command:
```
npx create-payload-app
```
Then just follow the prompts! You'll get set up with a new folder and a functioning Payload app inside. You can then start [configuring your application](../configuration/overview).
## Adding to an existing app
Adding Payload to an existing Next.js app is super straightforward. You can either run the `npx create-payload-app` command inside your Next.js project's folder, or manually install Payload by following the steps below.
If you don't have a Next.js app already, but you still want to start a project from a blank Next.js app, you can create a new Next.js app using `npx create-next-app` - and then just follow the steps below to install Payload.
<Banner type="info">
**Note:** Next.js version 15 or higher is required for Payload.
</Banner>
#### 1. Install the relevant packages
First, you'll want to add the required Payload packages to your project and can do so by running the command below:
```bash
pnpm i payload @payloadcms/next @payloadcms/richtext-lexical sharp graphql
```
<Banner type="warning">
**Note:** Swap out `pnpm` for your package manager. If you are using npm, you
might need to install using legacy peer deps: `npm i --legacy-peer-deps`.
</Banner>
Next, install a [Database Adapter](../database/overview). Payload requires a Database Adapter to establish a database connection. Payload works with all types of databases, but the most common are MongoDB and Postgres.
To install a Database Adapter, you can run **one** of the following commands:
- To install the [MongoDB Adapter](../database/mongodb), run:
```bash
pnpm i @payloadcms/db-mongodb
```
- To install the [Postgres Adapter](../database/postgres), run:
```bash
pnpm i @payloadcms/db-postgres
```
- To install the [SQLite Adapter](../database/sqlite), run:
```bash
pnpm i @payloadcms/db-sqlite
```
<Banner type="success">
**Note:** New [Database Adapters](../database/overview) are becoming
available every day. Check the docs for the most up-to-date list of what's
available.
</Banner>
#### 2. Copy Payload files into your Next.js app folder
Payload installs directly in your Next.js `/app` folder, and you'll need to place some files into that folder for Payload to run. You can copy these files from the [Blank Template](https://github.com/payloadcms/payload/tree/main/templates/blank/src/app/%28payload%29) on GitHub. Once you have the required Payload files in place in your `/app` folder, you should have something like this:
```plaintext
app/
├─ (payload)/
├── // Payload files
├─ (my-app)/
├── // Your app files
```
_For an exact reference of the `(payload)` directory, see [Project Structure](../admin/overview#project-structure)._
<Banner type="warning">
You may need to copy all of your existing frontend files, including your
existing root layout, into its own newly created [Route
Group](https://nextjs.org/docs/app/building-your-application/routing/route-groups),
i.e. `(my-app)`.
</Banner>
The files that Payload needs to have in your `/app` folder do not regenerate, and will never change. Once you slot them in, you never have to revisit them. They are not meant to be edited and simply import Payload dependencies from `@payloadcms/next` for the REST / GraphQL API and Admin Panel.
You can name the `(my-app)` folder anything you want. The name does not matter and will just be used to clarify your directory structure for yourself. Common names might be `(frontend)`, `(app)`, or similar. [More details](../admin/overview).
#### 3. Add the Payload Plugin to your Next.js config
Payload has a Next.js plugin that it uses to ensure compatibility with some of the packages Payload relies on, like `mongodb` or `drizzle-kit`.
To add the Payload Plugin, use `withPayload` in your `next.config.js`:
```js
import { withPayload } from '@payloadcms/next/withPayload'
/** @type {import('next').NextConfig} */
const nextConfig = {
// Your Next.js config here
experimental: {
reactCompiler: false,
},
}
// Make sure you wrap your `nextConfig`
// with the `withPayload` plugin
export default withPayload(nextConfig) // highlight-line
```
<Banner type="warning">
**Important:** Payload is a fully ESM project, and that means the
`withPayload` function is an ECMAScript module.
</Banner>
To import the Payload Plugin, you need to make sure your `next.config` file is set up to use ESM.
You can do this in one of two ways:
1. Set your own project to use ESM, by adding `"type": "module"` to your `package.json` file
2. Give your Next.js config the `.mjs` file extension
In either case, all `require`s and `export`s in your `next.config` file will need to be converted to `import` / `export` if they are not set up that way already.
#### 4. Create a Payload Config and add it to your TypeScript config
Finally, you need to create a [Payload Config](../configuration/overview). Generally the Payload Config is located at the root of your repository, or next to your `/app` folder, and is named `payload.config.ts`.
Here's what Payload needs at a bare minimum:
```ts
import sharp from 'sharp'
import { lexicalEditor } from '@payloadcms/richtext-lexical'
import { mongooseAdapter } from '@payloadcms/db-mongodb'
import { buildConfig } from 'payload'
export default buildConfig({
// If you'd like to use Rich Text, pass your editor here
editor: lexicalEditor(),
// Define and configure your collections in this array
collections: [],
// Your Payload secret - should be a complex and secure string, unguessable
secret: process.env.PAYLOAD_SECRET || '',
// Whichever Database Adapter you're using should go here
// Mongoose is shown as an example, but you can also use Postgres
db: mongooseAdapter({
url: process.env.DATABASE_URL || '',
}),
// If you want to resize images, crop, set focal point, etc.
// make sure to install it and pass it to the config.
// This is optional - if you don't need to do these things,
// you don't need it!
sharp,
})
```
Although this is just the bare minimum config, there are _many_ more options that you can control here. To reference the full config and all of its options, [click here](../configuration/overview).
Once you have a Payload Config, update your `tsconfig` to include a `path` that points to it:
```json
{
"compilerOptions": {
"paths": {
"@payload-config": ["./payload.config.ts"]
}
}
}
```
#### 5. Fire it up!
After you've reached this point, it's time to boot up Payload. Start your project in your application's folder to get going. By default, the Next.js dev script is `pnpm dev` (or `npm run dev` if using npm).
After it starts, you can go to `http://localhost:3000/admin` to create your first Payload user!
# The Payload Config
Source: https://payloadcms.com/docs/configuration/overview
Payload is a _config-based_, code-first CMS and application framework. The Payload Config is central to everything that Payload does, allowing for deep configuration of your application through a simple and intuitive API. The Payload Config is a fully-typed JavaScript object that can be infinitely extended upon.
Everything from your [Database](../database/overview) choice to the appearance of the [Admin Panel](../admin/overview) is fully controlled through the Payload Config. From here you can define [Fields](../fields/overview), add [Localization](./localization), enable [Authentication](../authentication/overview), configure [Access Control](../access-control/overview), and so much more.
The Payload Config is a `payload.config.ts` file typically located in the root of your project:
```ts
import { buildConfig } from 'payload'
export default buildConfig({
// Your config goes here
})
```
The Payload Config is strongly typed and ties directly into Payload's TypeScript codebase. This means your IDE (such as VSCode) will provide helpful information like type-ahead suggestions while you write your config.
<Banner type="success">
**Tip:** The location of your Payload Config can be customized. [More
details](#customizing-the-config-location).
</Banner>
## Config Options
To author your Payload Config, first determine which [Database](../database/overview) you'd like to use, then use [Collections](./collections) or [Globals](./globals) to define the schema of your data through [Fields](../fields/overview).
Here is one of the simplest possible Payload configs:
```ts
import { buildConfig } from 'payload'
import { mongooseAdapter } from '@payloadcms/db-mongodb'
export default buildConfig({
secret: process.env.PAYLOAD_SECRET,
db: mongooseAdapter({
url: process.env.DATABASE_URL,
}),
collections: [
{
slug: 'pages',
fields: [
{
name: 'title',
type: 'text',
},
],
},
],
})
```
<Banner type="success">
**Note:** For more complex examples, see the
[Templates](https://github.com/payloadcms/payload/tree/main/templates) and
[Examples](https://github.com/payloadcms/payload/tree/main/examples)
directories in the Payload repository.
</Banner>
The following options are available:
| Option | Description |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`admin`** | The configuration options for the Admin Panel, including Custom Components, Live Preview, etc. [More details](../admin/overview#admin-options). |
| **`bin`** | Register custom bin scripts for Payload to execute. [More Details](#custom-bin-scripts). |
| **`editor`** | The Rich Text Editor which will be used by `richText` fields. [More details](../rich-text/overview). |
| **`db`** \* | The Database Adapter which will be used by Payload. [More details](../database/overview). |
| **`serverURL`** | A string used to define the absolute URL of your app. This includes the protocol, for example `https://example.com`. No paths allowed, only protocol, domain and (optionally) port. |
| **`collections`** | An array of Collections for Payload to manage. [More details](./collections). |
| **`compatibility`** | Compatibility flags for earlier versions of Payload. [More details](#compatibility-flags). |
| **`globals`** | An array of Globals for Payload to manage. [More details](./globals). |
| **`cors`** | Cross-origin resource sharing (CORS) is a mechanism that accept incoming requests from given domains. You can also customize the `Access-Control-Allow-Headers` header. [More details](#cors). |
| **`localization`** | Opt-in to translate your content into multiple locales. [More details](./localization). |
| **`logger`** | Logger options, logger options with a destination stream, or an instantiated logger instance. [More details](https://getpino.io/#/docs/api?id=options). |
| **`loggingLevels`** | An object to override the level to use in the logger for Payload's errors. |
| **`graphQL`** | Manage GraphQL-specific functionality, including custom queries and mutations, query complexity limits, etc. [More details](../graphql/overview#graphql-options). |
| **`cookiePrefix`** | A string that will be prefixed to all cookies that Payload sets. |
| **`csrf`** | A whitelist array of URLs to allow Payload to accept cookies from. [More details](../authentication/cookies#csrf-attacks). |
| **`defaultDepth`** | If a user does not specify `depth` while requesting a resource, this depth will be used. [More details](../queries/depth). |
| **`defaultMaxTextLength`** | The maximum allowed string length to be permitted application-wide. Helps to prevent malicious public document creation. |
| `folders` | An optional object to configure global folder settings. [More details](../folders/overview). |
| `queryPresets` | An object that to configure Collection Query Presets. [More details](../query-presets/overview). |
| **`maxDepth`** | The maximum allowed depth to be permitted application-wide. This setting helps prevent against malicious queries. Defaults to `10`. [More details](../queries/depth). |
| **`indexSortableFields`** | Automatically index all sortable top-level fields in the database to improve sort performance and add database compatibility for Azure Cosmos and similar. |
| **`upload`** | Base Payload upload configuration. [More details](../upload/overview#payload-wide-upload-options). |
| **`routes`** | Control the routing structure that Payload binds itself to. [More details](../admin/overview#root-level-routes). |
| **`email`** | Configure the Email Adapter for Payload to use. [More details](../email/overview). |
| **`onInit`** | A function that is called immediately following startup that receives the Payload instance as its only argument. |
| **`debug`** | Enable to expose more detailed error information. |
| **`telemetry`** | Disable Payload telemetry by passing `false`. [More details](#telemetry). |
| **`hooks`** | An array of Root Hooks. [More details](../hooks/overview). |
| **`plugins`** | An array of Plugins. [More details](../plugins/overview). |
| **`endpoints`** | An array of Custom Endpoints added to the Payload router. [More details](../rest-api/overview#custom-endpoints). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins). |
| **`i18n`** | Internationalization configuration. Pass all i18n languages you'd like the admin UI to support. Defaults to English-only. [More details](./i18n). |
| **`secret`** \* | A secure, unguessable string that Payload will use for any encryption workflows - for example, password salt / hashing. |
| **`sharp`** | If you would like Payload to offer cropping, focal point selection, and automatic media resizing, install and pass the Sharp module to the config here. |
| **`typescript`** | Configure TypeScript settings here. [More details](#typescript). |
_\* An asterisk denotes that a property is required._
<Banner type="warning">
**Note:** Some properties are removed from the client-side bundle. [More
details](../custom-components/overview#accessing-the-payload-config).
</Banner>
### TypeScript Config
Payload exposes a variety of TypeScript settings that you can leverage. These settings are used to auto-generate TypeScript interfaces for your [Collections](./collections) and [Globals](./globals), and to ensure that Payload uses your [Generated Types](../typescript/overview) for all [Local API](../local-api/overview) methods.
To customize the TypeScript settings, use the `typescript` property in your Payload Config:
```ts
import { buildConfig } from 'payload'
export default buildConfig({
// ...
// highlight-start
typescript: {
// ...
},
// highlight-end
})
```
The following options are available:
| Option | Description |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`autoGenerate`** | By default, Payload will auto-generate TypeScript interfaces for all collections and globals that your config defines. Opt out by setting `typescript.autoGenerate: false`. [More details](../typescript/overview). |
| **`declare`** | By default, Payload adds a `declare` block to your generated types, which makes sure that Payload uses your generated types for all Local API methods. Opt out by setting `typescript.declare: false`. |
| **`outputFile`** | Control the output path and filename of Payload's auto-generated types by defining the `typescript.outputFile` property to a full, absolute path. |
| **`strictDraftTypes`** | Enable strict type safety for draft mode queries. When enabled, `find` operations with `draft: true` will type required fields as optional, since validation is skipped for drafts. Defaults to `false`. **This will become the default behavior in v4.0.** |
## Config Location
For Payload command-line scripts, we need to be able to locate your Payload Config. We'll check a variety of locations for the presence of `payload.config.ts` by default, including:
1. The root current working directory
1. The `compilerOptions` in your `tsconfig`\*
1. The `dist` directory\*
_\* Config location detection is different between development and production environments. See below for more details._
<Banner type="warning">
**Important:** Ensure your `tsconfig.json` is properly configured for Payload
to auto-detect your config location. If it does not exist, or does not specify
the proper `compilerOptions`, Payload will default to the current working
directory.
</Banner>
**Development Mode**
In development mode, if the configuration file is not found at the root, Payload will attempt to read your `tsconfig.json`, and attempt to find the config file specified in the `rootDir`:
```json
{
// ...
// highlight-start
"compilerOptions": {
"rootDir": "src"
}
// highlight-end
}
```
**Production Mode**
In production mode, Payload will first attempt to find the config file in the `outDir` of your `tsconfig.json`, and if not found, will fallback to the `rootDir` directory:
```json
{
// ...
// highlight-start
"compilerOptions": {
"outDir": "dist",
"rootDir": "src"
}
// highlight-end
}
```
If none was in either location, Payload will finally check the `dist` directory.
### Customizing the Config Location
In addition to the above automated detection, you can specify your own location for the Payload Config. This can be useful in situations where your config is not in a standard location, or you wish to switch between multiple configurations. To do this, Payload exposes an [Environment Variable](../configuration/environment-vars) to bypass all automatic config detection.
To use a custom config location, set the `PAYLOAD_CONFIG_PATH` environment variable:
```json
{
"scripts": {
"payload": "PAYLOAD_CONFIG_PATH=/path/to/custom-config.ts payload"
}
}
```
<Banner type="info">
**Tip:** `PAYLOAD_CONFIG_PATH` can be either an absolute path, or path
relative to your current working directory.
</Banner>
## Telemetry
Payload collects **completely anonymous** telemetry data about general usage. This data is super important to us and helps us accurately understand how we're growing and what we can do to build the software into everything that it can possibly be. The telemetry that we collect also help us demonstrate our growth in an accurate manner, which helps us as we seek investment to build and scale our team. If we can accurately demonstrate our growth, we can more effectively continue to support Payload as free and open-source software. To opt out of telemetry, you can pass `telemetry: false` within your Payload Config.
For more information about what we track, take a look at our [privacy policy](/privacy).
## Cross-origin resource sharing (CORS)#cors
Cross-origin resource sharing (CORS) can be configured with either a whitelist array of URLS to allow CORS requests from, a wildcard string (`*`) to accept incoming requests from any domain, or an object with the following properties:
| Option | Description |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| **`origins`** | Either a whitelist array of URLS to allow CORS requests from, or a wildcard string (`'*'`) to accept incoming requests from any domain. |
| **`headers`** | A list of allowed headers that will be appended in `Access-Control-Allow-Headers`. |
Here's an example showing how to allow incoming requests from any domain:
```ts
import { buildConfig } from 'payload'
export default buildConfig({
// ...
// highlight-start
cors: '*',
// highlight-end
})
```
Here's an example showing how to append a new header (`x-custom-header`) in `Access-Control-Allow-Headers`:
```ts
import { buildConfig } from 'payload'
export default buildConfig({
// ...
// highlight-start
cors: {
origins: ['http://localhost:3000'],
headers: ['x-custom-header'],
},
// highlight-end
})
```
## TypeScript
You can import types from Payload to help make writing your config easier and type-safe. There are two main types that represent the Payload Config, `Config` and `SanitizedConfig`.
The `Config` type represents a raw Payload Config in its full form. Only the bare minimum properties are marked as required. The `SanitizedConfig` type represents a Payload Config after it has been fully sanitized. Generally, this is only used internally by Payload.
```ts
import type { Config, SanitizedConfig } from 'payload'
```
## Server vs. Client
The Payload Config only lives on the server and is not allowed to contain any client-side code. That way, you can load up the Payload Config in any server environment or standalone script, without having to use Bundlers or Node.js loaders to handle importing client-only modules (e.g. scss files or React Components) without any errors.
Behind the curtains, the Next.js-based Admin Panel generates a ClientConfig, which strips away any server-only code and enriches the config with React Components.
## Compatibility flags
The Payload Config can accept compatibility flags for running the newest versions but with older databases. You should only use these flags if you need to, and should confirm that you need to prior to enabling these flags.
`allowLocalizedWithinLocalized`
Payload localization works on a field-by-field basis. As you can nest fields within other fields, you could potentially nest a localized field within a localized field—but this would be redundant and unnecessary. There would be no reason to define a localized field within a localized parent field, given that the entire data structure from the parent field onward would be localized.
By default, Payload will remove the `localized: true` property from sub-fields if a parent field is localized. Set this compatibility flag to `true` only if you have an existing Payload MongoDB database from pre-3.0, and you have nested localized fields that you would like to maintain without migrating.
## Custom bin scripts
Using the `bin` configuration property, you can inject your own scripts to `npx payload`.
Example for `pnpm payload seed`:
Step 1: create `seed.ts` file in the same folder with `payload.config.ts` with:
```ts
import type { SanitizedConfig } from 'payload'
import payload from 'payload'
// Script must define a "script" function export that accepts the sanitized config
export const script = async (config: SanitizedConfig) => {
await payload.init({ config })
await payload.create({
collection: 'pages',
data: { title: 'my title' },
})
payload.logger.info('Successfully seeded!')
process.exit(0)
}
```
Step 2: add the `seed` script to `bin`:
```ts
export default buildConfig({
bin: [
{
scriptPath: path.resolve(dirname, 'seed.ts'),
key: 'seed',
},
],
})
```
Now you can run the command using:
```sh
pnpm payload seed
```
## Running bin scripts on a schedule
Every bin script supports being run on a schedule using cron syntax. Simply pass the `--cron` flag followed by the cron expression when running the script. Example:
```sh
pnpm payload run ./myScript.ts --cron "0 * * * *"
```
This will use the `run` bin script to execute the specified script on the defined schedule.
# Collection Configs
Source: https://payloadcms.com/docs/configuration/collections
A Collection is a group of records, called Documents, that all share a common schema. You can define as many Collections as your application needs. Each Document in a Collection is stored in the [Database](../database/overview) based on the [Fields](../fields/overview) that you define, and automatically generates a [Local API](../local-api/overview), [REST API](../rest-api/overview), and [GraphQL API](../graphql/overview) used to manage your Documents.
Collections are also used to achieve [Authentication](../authentication/overview) in Payload. By defining a Collection with `auth` options, that Collection receives additional operations to support user authentication.
Collections are the primary way to structure recurring data in your application, such as users, products, pages, posts, and other types of content that you might want to manage. Each Collection can have its own unique [Access Control](../access-control/overview), [Hooks](../hooks/overview), [Admin Options](#admin-options), and more.
To define a Collection Config, use the `collection` property in your [Payload Config](./overview):
```ts
import { buildConfig } from 'payload'
export default buildConfig({
// ...
collections: [
// highlight-line
// Your Collections go here
],
})
```
<Banner type="success">
**Tip:** If your Collection is only ever meant to contain a single Document,
consider using a [Global](./globals) instead.
</Banner>
## Config Options
It's often best practice to write your Collections in separate files and then import them into the main [Payload Config](./overview).
Here is what a simple Collection Config might look like:
```ts
import type { CollectionConfig } from 'payload'
export const Posts: CollectionConfig = {
slug: 'posts',
fields: [
{
name: 'title',
type: 'text',
},
],
}
```
<Banner type="success">
**Reminder:** For more complex examples, see the
[Templates](https://github.com/payloadcms/payload/tree/main/templates) and
[Examples](https://github.com/payloadcms/payload/tree/main/examples)
directories in the Payload repository.
</Banner>
The following options are available:
| Option | Description |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `admin` | The configuration options for the Admin Panel. [More details](#admin-options). |
| `access` | Provide Access Control functions to define exactly who should be able to do what with Documents in this Collection. [More details](../access-control/collections). |
| `auth` | Specify options if you would like this Collection to feature authentication. [More details](../authentication/overview). |
| `custom` | Extension point for adding custom data (e.g. for plugins) |
| `disableDuplicate` | When true, do not show the "Duplicate" button while editing documents within this Collection and prevent `duplicate` from all APIs. |
| `defaultSort` | Pass a top-level field to sort by default in the Collection List View. Prefix the name of the field with a minus symbol ("-") to sort in descending order. Multiple fields can be specified by using a string array. |
| `dbName` | Custom table or Collection name depending on the Database Adapter. Auto-generated from slug if not defined. |
| `endpoints` | Add custom routes to the REST API. Set to `false` to disable routes. [More details](../rest-api/overview#custom-endpoints). |
| `fields` \* | Array of field types that will determine the structure and functionality of the data stored within this Collection. [More details](../fields/overview). |
| `graphQL` | Manage GraphQL-related properties for this collection. [More](#graphql) |
| `hooks` | Entry point for Hooks. [More details](../hooks/overview#collection-hooks). |
| `orderable` | If true, enables custom ordering for the collection, and documents can be reordered via drag and drop. Uses [orderable](#orderable) for efficient reordering. |
| `labels` | Singular and plural labels for use in identifying this Collection throughout Payload. Auto-generated from slug if not defined. |
| `enableQueryPresets` | Enable query presets for this Collection. [More details](../query-presets/overview). |
| `lockDocuments` | Enables or disables document locking. By default, document locking is enabled. Set to an object to configure, or set to `false` to disable locking. [More details](../admin/locked-documents). |
| `slug` \* | Unique, URL-friendly string that will act as an identifier for this Collection. |
| `timestamps` | Set to false to disable documents' automatically generated `createdAt` and `updatedAt` timestamps. |
| `trash` | A boolean to enable soft deletes for this collection. Defaults to `false`. [More details](../trash/overview). |
| `typescript` | An object with property `interface` as the text used in schema generation. Auto-generated from slug if not defined. |
| `upload` | Specify options if you would like this Collection to support file uploads. For more, consult the [Uploads](../upload/overview) documentation. |
| `versions` | Set to true to enable default options, or configure with object properties. [More details](../versions/overview#collection-config). |
| `defaultPopulate` | Specify which fields to select when this Collection is populated from another document. [More Details](../queries/select#defaultpopulate-collection-config-property). |
| `indexes` | Define compound indexes for this collection. This can be used to either speed up querying/sorting by 2 or more fields at the same time or to ensure uniqueness between several fields. |
| `forceSelect` | Specify which fields should be selected always, regardless of the `select` query which can be useful that the field exists for access control / hooks. [More details](../queries/select). |
| `disableBulkEdit` | Disable the bulk edit operation for the collection in the admin panel and the REST API |
_\* An asterisk denotes that a property is required._
### Fields
Fields define the schema of the Documents within a Collection. To learn more, go to the [Fields](../fields/overview) documentation.
### Access Control
[Collection Access Control](../access-control/collections) determines what a user can and cannot do with any given Document within a Collection. To learn more, go to the [Access Control](../access-control/overview) documentation.
### Hooks
[Collection Hooks](../hooks/collections) allow you to tie into the lifecycle of your Documents so you can execute your own logic during specific events. To learn more, go to the [Hooks](../hooks/overview) documentation.
### Orderable
When `orderable` is enabled, Payload uses [fractional indexing](https://observablehq.com/@dgreensp/implementing-fractional-indexing) to efficiently manage document order. When enabled on collections, this allows you to manually drag and drop documents in the Admin Panel to reorder them, as well as programmatically set the order of documents via the Local API, REST API, or GraphQL API.
Orderable can also be added to [joins fields](../fields/join).
#### Fractional indexing
If you need to generate order keys programmatically (e.g., when creating documents via the Local API with a specific order), you can import the utilities directly:
```ts
import { generateKeyBetween, generateNKeysBetween } from 'payload/shared'
// Generate a key between two existing keys (or null for start/end)
const newKey = generateKeyBetween('a0', 'a1')
// Generate a key at the start (before 'a0')
const startKey = generateKeyBetween(null, 'a0')
// Generate a key at the end (after 'a1')
const endKey = generateKeyBetween('a1', null)
// Generate multiple keys between two existing keys
const keys = generateNKeysBetween('a0', 'a1', 5)
```
These utilities are useful when you need fine-grained control over document ordering, such as inserting documents at specific positions or batch-creating documents with predetermined order.
## Admin Options
The behavior of Collections within the [Admin Panel](../admin/overview) can be fully customized to fit the needs of your application. This includes grouping or hiding their navigation links, adding [Custom Components](../custom-components/overview), selecting which fields to display in the List View, and more.
To configure Admin Options for Collections, use the `admin` property in your Collection Config:
```ts
import type { CollectionConfig } from 'payload'
export const MyCollection: CollectionConfig = {
// ...
admin: {
// highlight-line
// ...
},
}
```
The following options are available:
| Option | Description |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `group` | Text or localization object used to group Collection and Global links in the admin navigation. Set to `false` to hide the link from the navigation while keeping its routes accessible. |
| `hidden` | Set to true or a function, called with the current user, returning true to exclude this Collection from navigation and admin routing. |
| `hooks` | Admin-specific hooks for this Collection. [More details](../hooks/collections). |
| `useAsTitle` | Specify a top-level field to use for a document title throughout the Admin Panel. If no field is defined, the ID of the document is used as the title. |
| `description` | Text to display below the Collection label in the List View to give editors more information. Alternatively, you can use the `admin.components.Description` to render a React component. [More details](#custom-components). |
| `defaultColumns` | Array of field names that correspond to which columns to show by default in this Collection's List View. |
| `disableCopyToLocale` | Disables the "Copy to Locale" button while editing documents within this Collection. Only applicable when localization is enabled. |
| `groupBy` | Beta. Enable grouping by a field in the list view. |
| `hideAPIURL` | Hides the "API URL" meta field while editing documents within this Collection. |
| `enableRichTextLink` | The [Rich Text](../fields/rich-text) field features a `Link` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |
| `enableRichTextRelationship` | The [Rich Text](../fields/rich-text) field features a `Relationship` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |
| `folders` | A boolean to enable folders for a given collection. Defaults to `false`. [More details](../folders/overview). |
| `formatDocURL` | Function to customize document links in the List View. Return `null` to disable linking, or a string for custom URLs. [More details](#format-document-urls). |
| `meta` | Page metadata overrides to apply to this Collection within the Admin Panel. [More details](../admin/metadata). |
| `preview` | Function to generate preview URLs within the Admin Panel that can point to your app. [More details](../admin/preview). |
| `livePreview` | Enable real-time editing for instant visual feedback of your front-end application. [More details](../live-preview/overview). |
| `components` | Swap in your own React components to be used within this Collection. [More details](#custom-components). |
| `listSearchableFields` | Specify which fields should be searched in the List search view. [More details](#list-searchable-fields). |
| `enableListViewSelectAPI` | Performance opt-in. When `true`, uses the Select API in the List View to query only the active columns as opposed to entire documents. [More details](#enable-list-view-select-api). |
| `pagination` | Set pagination-specific options for this Collection in the List View. [More details](#pagination). |
| `baseFilter` | Defines a default base filter which will be applied to the List View (along with any other filters applied by the user) and internal links in Lexical Editor, |
<Banner type="warning">
**Note:** If you set `useAsTitle` to a relationship or join field, it will use
only the ID of the related document(s) as the title. To display a specific
field (i.e. title) from the related document instead, create a virtual field
that extracts the desired data, and set `useAsTitle` to that virtual field.
</Banner>
### Custom Components
Collections can set their own [Custom Components](../custom-components/overview) which only apply to Collection-specific UI within the [Admin Panel](../admin/overview). This includes elements such as the Save Button, or entire layouts such as the Edit View.
To override Collection Components, use the `admin.components` property in your Collection Config:
```ts
import type { CollectionConfig } from 'payload'
export const MyCollection: CollectionConfig = {
// ...
admin: {
components: {
// highlight-line
// ...
},
},
}
```
The following options are available:
| Option | Description |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `afterList` | An array of components to inject _after_ the built-in List View. [More details](../custom-components/list-view#afterlist). |
| `afterListTable` | An array of components to inject _after_ the built-in List View's table. [More details](../custom-components/list-view#afterlisttable). |
| `beforeList` | An array of components to inject _before_ the built-in List View. [More details](../custom-components/list-view#beforelist). |
| `beforeListTable` | An array of components to inject _before_ the built-in List View's table. [More details](../custom-components/list-view#beforelisttable). |
| `listMenuItems` | An array of components to render within a menu next to the List Controls (after the Columns and Filters options) |
| `Description` | A component to render below the Collection label in the List View. An alternative to the `admin.description` property. [More details](../custom-components/list-view#description). |
| `edit` | Override specific components within the Edit View. [More details](#edit-view-options). |
| `views` | Override or create new views within the Admin Panel. [More details](../custom-components/custom-views). |
#### Edit View Options
```ts
import type { CollectionConfig } from 'payload'
export const MyCollection: CollectionConfig = {
// ...
admin: {
components: {
edit: {
// highlight-line
// ...
},
},
},
}
```
The following options are available:
| Option | Description |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `beforeDocumentControls` | Inject custom components before the Save / Publish buttons. [More details](../custom-components/edit-view#beforedocumentcontrols). |
| `editMenuItems` | Inject custom components within the 3-dot menu dropdown located in the document controls bar. [More details](../custom-components/edit-view#editmenuitems). |
| `SaveButton` | Replace the default Save Button within the Edit View. [Drafts](../versions/drafts) must be disabled. [More details](../custom-components/edit-view#savebutton). |
| `SaveDraftButton` | Replace the default Save Draft Button within the Edit View. [Drafts](../versions/drafts) must be enabled and autosave must be disabled. [More details](../custom-components/edit-view#savedraftbutton). |
| `Status` | Replace the default Status component within the Edit View. [Drafts](../versions/drafts) must be enabled. [More details](../custom-components/edit-view#status). |
| `PublishButton` | Replace the default Publish Button within the Edit View. [Drafts](../versions/drafts) must be enabled. [More details](../custom-components/edit-view#publishbutton). |
| `UnpublishButton` | Replace the default Unpublish Button within the Edit View. [Drafts](../versions/drafts) must be enabled. [More details](../custom-components/edit-view#unpublishbutton). |
| `PreviewButton` | Replace the default Preview Button within the Edit View. [Preview](../admin/preview) must be enabled. [More details](../custom-components/edit-view#previewbutton). |
| `Upload` | Replace the default Upload component within the Edit View. [Upload](../upload/overview) must be enabled. [More details](../custom-components/edit-view#upload). |
<Banner type="success">
**Note:** For details on how to build Custom Components, see [Building Custom
Components](../custom-components/overview#building-custom-components).
</Banner>
### Pagination
All Collections receive their own List View which displays a paginated list of documents that can be sorted and filtered. The pagination behavior of the List View can be customized on a per-Collection basis, and uses the same [Pagination](../queries/pagination) API that Payload provides.
To configure pagination options, use the `admin.pagination` property in your Collection Config:
```ts
import type { CollectionConfig } from 'payload'
export const Posts: CollectionConfig = {
// ...
admin: {
// highlight-start
pagination: {
defaultLimit: 10,
limits: [10, 20, 50],
},
// highlight-end
},
}
```
The following options are available:
| Option | Description |
| -------------- | --------------------------------------------------------------------------------------------------- |
| `defaultLimit` | Integer that specifies the default per-page limit that should be used. Defaults to 10. |
| `limits` | Provide an array of integers to use as per-page options for admins to choose from in the List View. |
### List Searchable Fields
In the List View, there is a "search" box that allows you to quickly find a document through a simple text search. By default, it searches on the ID field. If defined, the `admin.useAsTitle` field is used. Or, you can explicitly define which fields to search based on the needs of your application.
To define which fields should be searched, use the `admin.listSearchableFields` property in your Collection Config:
```ts
import type { CollectionConfig } from 'payload'
export const Posts: CollectionConfig = {
// ...
admin: {
// highlight-start
listSearchableFields: ['title', 'slug'],
// highlight-end
},
}
```
<Banner type="warning">
**Tip:** If you are adding `listSearchableFields`, make sure you index each of
these fields so your admin queries can remain performant.
</Banner>
## Enable List View Select API
When `true`, the List View will use the [Select API](../queries/select) to query only the _active_ columns as opposed to entire documents. This can greatly improve performance, especially for collections with large documents or many fields.
To enable this, set `enableListViewSelectAPI: true` in your Collection Config:
```ts
import type { CollectionConfig } from 'payload'
export const Posts: CollectionConfig = {
// ...
admin: {
// ...
// highlight-start
enableListViewSelectAPI: true,
// highlight-end
},
}
```
<Banner type="info">
**Note:** The `enableListViewSelectAPI` property is labeled as experimental,
as it will likely become the default behavior in v4 and be deprecated.
</Banner>
Enabling this feature may cause unexpected behavior in some cases, however, such as when using hooks that rely on the full document data.
For example, if your component relies on a "title" field, this field will no longer be populated if the column is inactive:
```ts
import type { CollectionConfig } from 'payload'
export const Posts: CollectionConfig = {
// ...
fields: [
// ...
{
name: 'myField',
type: 'text',
hooks: {
afterRead: [
({ doc }) => doc.title, // The `title` field will no longer be populated by default, unless the column is active
],
},
},
],
}
```
To ensure title is always present, you will need to add that field to the [`forceSelect`](../queries/select) property in your Collection Config:
```ts
export const Posts: CollectionConfig = {
// ...
forceSelect: {
title: true,
},
}
```
### Format Document URLs
The `formatDocURL` function allows you to customize how document links are generated in the List View. This is useful for disabling links for certain documents, redirecting to custom destinations, or modifying URLs based on user context or document state.
To define a custom document URL formatter, use the `admin.formatDocURL` property in your Collection Config:
```ts
import type { CollectionConfig } from 'payload'
export const Posts: CollectionConfig = {
// ...
admin: {
formatDocURL: ({ doc, defaultURL, req, collectionSlug, viewType }) => {
// Disable linking for documents with specific status
if (doc.status === 'private') {
return null
}
// Custom destination for featured posts
if (doc.featured) {
return '/admin/featured-posts'
}
// Add query parameters based on user role
if (req.user?.role === 'admin') {
return defaultURL + '?admin=true'
}
// Use default URL for all other cases
return defaultURL
},
},
}
```
The `formatDocURL` function receives the following arguments:
| Argument | Description |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `doc` | The document data for the current row |
| `defaultURL` | The default URL that Payload would normally generate for this document. You can return this as-is, modify it, or replace it entirely. |
| `req` | The full [PayloadRequest](../types/payload-request) object, providing access to user context, payload instance, and other request data |
| `collectionSlug` | The slug of the current collection |
| `viewType` | The current view context (`'list'`, `'trash'`, etc.) where the link is being generated |
The function should return:
- `null` to disable the link entirely (no link will be rendered)
- A `string` containing the custom URL to use for the link
- The `defaultURL` parameter to use Payload's default linking behavior
<Banner type="success">
**Tip:** The `defaultURL` parameter saves you from having to reconstruct URLs
manually. You can modify it by appending query parameters or use it as a
fallback for your custom logic.
</Banner>
#### Examples
**Disable linking for certain users:**
```ts
formatDocURL: ({ defaultURL, req }) => {
if (req.user?.role === 'editor') {
return null // No link rendered
}
return defaultURL
}
```
## GraphQL
You can completely disable GraphQL for this collection by passing `graphQL: false` to your collection config. This will completely disable all queries, mutations, and types from appearing in your GraphQL schema.
You can also pass an object to the collection's `graphQL` property, which allows you to define the following properties:
| Option | Description |
| ------------------ | ----------------------------------------------------------------------------------- |
| `singularName` | Override the "singular" name that will be used in GraphQL schema generation. |
| `pluralName` | Override the "plural" name that will be used in GraphQL schema generation. |
| `disableQueries` | Disable all GraphQL queries that correspond to this collection by passing `true`. |
| `disableMutations` | Disable all GraphQL mutations that correspond to this collection by passing `true`. |
## TypeScript
You can import types from Payload to help make writing your Collection configs easier and type-safe. There are two main types that represent the Collection Config, `CollectionConfig` and `SanitizedCollectionConfig`.
The `CollectionConfig` type represents a raw Collection Config in its full form, where only the bare minimum properties are marked as required. The `SanitizedCollectionConfig` type represents a Collection Config after it has been fully sanitized. Generally, this is only used internally by Payload.
```ts
import type { CollectionConfig, SanitizedCollectionConfig } from 'payload'
```
# Global Configs
Source: https://payloadcms.com/docs/configuration/globals
Globals are in many ways similar to [Collections](./collections), except that they correspond to only a single Document. You can define as many Globals as your application needs. Each Global Document is stored in the [Database](../database/overview) based on the [Fields](../fields/overview) that you define, and automatically generates a [Local API](../local-api/overview), [REST API](../rest-api/overview), and [GraphQL API](../graphql/overview) used to manage your Documents.
Globals are the primary way to structure singletons in Payload, such as a header navigation, site-wide banner alerts, or app-wide localized strings. Each Global can have its own unique [Access Control](../access-control/overview), [Hooks](../hooks/overview), [Admin Options](#admin-options), and more.
To define a Global Config, use the `globals` property in your [Payload Config](./overview):
```ts
import { buildConfig } from 'payload'
export default buildConfig({
// ...
globals: [
// highlight-line
// Your Globals go here
],
})
```
<Banner type="success">
**Tip:** If you have more than one Global that share the same structure,
consider using a [Collection](./collections) instead.
</Banner>
## Config Options
It's often best practice to write your Globals in separate files and then import them into the main [Payload Config](./overview).
Here is what a simple Global Config might look like:
```ts
import { GlobalConfig } from 'payload'
export const Nav: GlobalConfig = {
slug: 'nav',
fields: [
{
name: 'items',
type: 'array',
required: true,
maxRows: 8,
fields: [
{
name: 'page',
type: 'relationship',
relationTo: 'pages', // "pages" is the slug of an existing collection
required: true,
},
],
},
],
}
```
<Banner type="success">
**Reminder:** For more complex examples, see the
[Templates](https://github.com/payloadcms/payload/tree/main/templates) and
[Examples](https://github.com/payloadcms/payload/tree/main/examples)
directories in the Payload repository.
</Banner>
The following options are available:
| Option | Description |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `access` | Provide Access Control functions to define exactly who should be able to do what with this Global. [More details](../access-control/globals). |
| `admin` | The configuration options for the Admin Panel. [More details](#admin-options). |
| `custom` | Extension point for adding custom data (e.g. for plugins) |
| `dbName` | Custom table or collection name for this Global depending on the Database Adapter. Auto-generated from slug if not defined. |
| `description` | Text or React component to display below the Global header to give editors more information. |
| `endpoints` | Add custom routes to the REST API. [More details](../rest-api/overview#custom-endpoints). |
| `fields` \* | Array of field types that will determine the structure and functionality of the data stored within this Global. [More details](../fields/overview). |
| `graphQL` | Manage GraphQL-related properties related to this global. [More details](#graphql) |
| `hooks` | Entry point for Hooks. [More details](../hooks/overview#global-hooks). |
| `label` | Text for the name in the Admin Panel or an object with keys for each language. Auto-generated from slug if not defined. |
| `lockDocuments` | Enables or disables document locking. By default, document locking is enabled. Set to an object to configure, or set to `false` to disable locking. [More details](../admin/locked-documents). |
| `slug` \* | Unique, URL-friendly string that will act as an identifier for this Global. |
| `typescript` | An object with property `interface` as the text used in schema generation. Auto-generated from slug if not defined. |
| `versions` | Set to true to enable default options, or configure with object properties. [More details](../versions/overview#global-config). |
| `forceSelect` | Specify which fields should be selected always, regardless of the `select` query which can be useful that the field exists for access control / hooks. [More details](../queries/select). |
_\* An asterisk denotes that a property is required._
### Fields
Fields define the schema of the Global. To learn more, go to the [Fields](../fields/overview) documentation.
### Access Control
[Global Access Control](../access-control/globals) determines what a user can and cannot do with any given Global Document. To learn more, go to the [Access Control](../access-control/overview) documentation.
### Hooks
[Global Hooks](../hooks/globals) allow you to tie into the lifecycle of your Documents so you can execute your own logic during specific events. To learn more, go to the [Hooks](../hooks/overview) documentation.
## Admin Options
The behavior of Globals within the [Admin Panel](../admin/overview) can be fully customized to fit the needs of your application. This includes grouping or hiding their navigation links, adding [Custom Components](../custom-components/overview), setting page metadata, and more.
To configure Admin Options for Globals, use the `admin` property in your Global Config:
```ts
import { GlobalConfig } from 'payload'
export const MyGlobal: GlobalConfig = {
// ...
admin: {
// highlight-line
// ...
},
}
```
The following options are available:
| Option | Description |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `group` | Text or localization object used to group Collection and Global links in the admin navigation. Set to `false` to hide the link from the navigation while keeping its routes accessible. |
| `hidden` | Set to true or a function, called with the current user, returning true to exclude this Global from navigation and admin routing. |
| `components` | Swap in your own React components to be used within this Global. [More details](#custom-components). |
| `preview` | Function to generate a preview URL within the Admin Panel for this Global that can point to your app. [More details](../admin/preview). |
| `livePreview` | Enable real-time editing for instant visual feedback of your front-end application. [More details](../live-preview/overview). |
| `hideAPIURL` | Hides the "API URL" meta field while editing documents within this collection. |
| `meta` | Page metadata overrides to apply to this Global within the Admin Panel. [More details](../admin/metadata). |
### Custom Components
Globals can set their own [Custom Components](../custom-components/overview) which only apply to Global-specific UI within the [Admin Panel](../admin/overview). This includes elements such as the Save Button, or entire layouts such as the Edit View.
To override Global Components, use the `admin.components` property in your Global Config:
```ts
import type { SanitizedGlobalConfig } from 'payload'
export const MyGlobal: SanitizedGlobalConfig = {
// ...
admin: {
components: {
// highlight-line
// ...
},
},
}
```
The following options are available:
#### General
| Option | Description |
| ---------- | ------------------------------------------------------------------------------------------------------- |
| `elements` | Override or create new elements within the Edit View. [More details](#edit-view-options). |
| `views` | Override or create new views within the Admin Panel. [More details](../custom-components/custom-views). |
#### Edit View Options
```ts
import type { SanitizedGlobalConfig } from 'payload'
export const MyGlobal: SanitizedGlobalConfig = {
// ...
admin: {
components: {
elements: {
// highlight-line
// ...
},
},
},
}
```
The following options are available:
| Option | Description |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `beforeDocumentControls` | Inject custom components before the Save button. [More details](../custom-components/edit-view#beforedocumentcontrols). |
| `Description` | A component to render below the Global label in the Edit View. [More details](../custom-components/edit-view#description). |
| `SaveButton` | Replace the default Save Button with a Custom Component. [Drafts](../versions/drafts) must be disabled. [More details](../custom-components/edit-view#savebutton). |
| `SaveDraftButton` | Replace the default Save Draft Button with a Custom Component. [Drafts](../versions/drafts) must be enabled and autosave must be disabled. [More details](../custom-components/edit-view#savedraftbutton). |
| `PublishButton` | Replace the default Publish Button with a Custom Component. [Drafts](../versions/drafts) must be enabled. [More details](../custom-components/edit-view#publishbutton). |
| `UnpublishButton` | Replace the default Unpublish Button with a Custom Component. [Drafts](../versions/drafts) must be enabled. [More details](../custom-components/edit-view#unpublishbutton). |
| `PreviewButton` | Replace the default Preview Button with a Custom Component. [Preview](../admin/preview) must be enabled. [More details](../custom-components/edit-view#previewbutton). |
| `Status` | Replace the default Status component with a Custom Component. [Drafts](../versions/drafts) must be enabled. [More details](../custom-components/edit-view#status). |
<Banner type="success">
**Note:** For details on how to build Custom Components, see [Building Custom
Components](../custom-components/overview#building-custom-components).
</Banner>
## GraphQL
You can completely disable GraphQL for this global by passing `graphQL: false` to your global config. This will completely disable all queries, mutations, and types from appearing in your GraphQL schema.
You can also pass an object to the global's `graphQL` property, which allows you to define the following properties:
| Option | Description |
| ------------------ | ------------------------------------------------------------------------------- |
| `name` | Override the name that will be used in GraphQL schema generation. |
| `disableQueries` | Disable all GraphQL queries that correspond to this global by passing `true`. |
| `disableMutations` | Disable all GraphQL mutations that correspond to this global by passing `true`. |
## TypeScript
You can import types from Payload to help make writing your Global configs easier and type-safe. There are two main types that represent the Global Config, `GlobalConfig` and `SanitizedGlobalConfig`.
The `GlobalConfig` type represents a raw Global Config in its full form, where only the bare minimum properties are marked as required. The `SanitizedGlobalConfig` type represents a Global Config after it has been fully sanitized. Generally, this is only used internally by Payload.
```ts
import type { GlobalConfig, SanitizedGlobalConfig } from 'payload'
```
# I18n
Source: https://payloadcms.com/docs/configuration/i18n
The [Admin Panel](../admin/overview) is translated in over [30 languages and counting](https://github.com/payloadcms/payload/tree/main/packages/translations). With I18n, editors can navigate the interface and read API error messages in their preferred language. This is similar to [Localization](./localization), but instead of managing translations for the data itself, you are managing translations for your application's interface.
By default, Payload comes preinstalled with English, but you can easily load other languages into your own application. Languages are automatically detected based on the request. If no language is detected, or if the user's language is not yet supported by your application, English will be chosen.
To add I18n to your project, you first need to install the `@payloadcms/translations` package:
```bash
pnpm install @payloadcms/translations
```
Once installed, it can be configured using the `i18n` key in your [Payload Config](./overview):
```ts
import { buildConfig } from 'payload'
export default buildConfig({
// ...
i18n: {
// highlight-line
// ...
},
})
```
<Banner type="success">
**Note:** If there is a language that Payload does not yet support, we accept
[code
contributions](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md).
</Banner>
## Config Options
You can easily customize and override any of the i18n settings that Payload provides by default. Payload will use your custom options and merge them in with its own.
```ts
import { buildConfig } from 'payload'
export default buildConfig({
// ...
// highlight-start
i18n: {
fallbackLanguage: 'en', // default
},
// highlight-end
})
```
The following options are available:
| Option | Description |
| -------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `fallbackLanguage` | The language to fall back to if the user's preferred language is not supported. Default is `'en'`. |
| `translations` | An object containing the translations. The keys are the language codes and the values are the translations. |
| `supportedLanguages` | An object containing the supported languages. The keys are the language codes and the values are the translations. |
## Adding Languages
You can easily add new languages to your Payload app by providing the translations for the new language. Payload maintains a number of built-in translations that can be imported from `@payloadcms/translations`, but you can also provide your own [Custom Translations](#custom-translations) to support any language.
To add a new language, use the `i18n.supportedLanguages` key in your [Payload Config](./overview):
```ts
import { buildConfig } from 'payload'
import { en } from '@payloadcms/translations/languages/en'
import { de } from '@payloadcms/translations/languages/de'
export default buildConfig({
// ...
// highlight-start
i18n: {
supportedLanguages: { en, de },
},
// highlight-end
})
```
<Banner type="warning">
**Tip:** It's best to only support the languages that you need so that the
bundled JavaScript is kept to a minimum for your project.
</Banner>
### Custom Translations
You can customize Payload's built-in translations either by extending existing languages or by adding new languages entirely. This can be done by injecting new translation strings into existing languages, or by providing an entirely new language keys altogether.
To add Custom Translations, use the `i18n.translations` key in your [Payload Config](./overview):
```ts
import { buildConfig } from 'payload'
export default buildConfig({
//...
i18n: {
// highlight-start
translations: {
en: {
custom: {
// namespace can be anything you want
key1: 'Translation with {{variable}}', // translation
},
// override existing translation keys
general: {
dashboard: 'Home',
},
},
},
// highlight-end
},
//...
})
```
### Project Translations
While Payload's built-in features come fully translated, you may also want to translate parts of your own project. This is possible in places like [Collections](./collections) and [Globals](./globals), such as on their labels and groups, field labels, descriptions or input placeholder text.
To do this, provide the translations wherever applicable, keyed to the language code:
```ts
import type { CollectionConfig } from 'payload'
export const Articles: CollectionConfig = {
slug: 'articles',
labels: {
singular: {
// highlight-start
en: 'Article',
es: 'Artículo',
// highlight-end
},
plural: {
// highlight-start
en: 'Articles',
es: 'Artículos',
// highlight-end
},
},
admin: {
group: {
// highlight-start
en: 'Content',
es: 'Contenido',
// highlight-end
},
},
fields: [
{
name: 'title',
type: 'text',
label: {
// highlight-start
en: 'Title',
es: 'Título',
// highlight-end
},
admin: {
placeholder: {
// highlight-start
en: 'Enter title',
es: 'Introduce el título',
// highlight-end
},
},
},
],
}
```
## Changing Languages
Users can change their preferred language in their account settings or by otherwise manipulating their [User Preferences](../admin/preferences).
## Node.js#node
Payload's backend sets the language on incoming requests before they are handled. This allows backend validation to return error messages in the user's own language or system generated emails to be sent using the correct translation. You can make HTTP requests with the `accept-language` header and Payload will use that language.
Anywhere in your Payload app that you have access to the `req` object, you can access Payload's extensive internationalization features assigned to `req.i18n`. To access text translations you can use `req.t('namespace:key')`.
## TypeScript
In order to use [Custom Translations](#custom-translations) in your project, you need to provide the types for the translations.
Here we create a shareable translations object. We will import this in both our custom components and in our Payload config.
In this example we show how to extend English, but you can do the same for any language you want.
```ts
// <rootDir>/custom-translations.ts
import { enTranslations } from '@payloadcms/translations/languages/en'
import type { NestedKeysStripped } from '@payloadcms/translations'
export const customTranslations = {
en: {
general: {
myCustomKey: 'My custom english translation',
},
fields: {
addLabel: 'Add!',
},
},
}
export type CustomTranslationsObject = typeof customTranslations.en &
typeof enTranslations
export type CustomTranslationsKeys =
NestedKeysStripped<CustomTranslationsObject>
```
Import the shared translations object into our Payload config so they are available for use:
```ts
// <rootDir>/payload.config.ts
import { buildConfig } from 'payload'
import { customTranslations } from './custom-translations'
export default buildConfig({
//...
i18n: {
translations: customTranslations,
},
//...
})
```
Import the shared translation types to use in your [Custom Component](../custom-components/overview):
```ts
// <rootDir>/components/MyComponent.tsx
'use client'
import type React from 'react'
import { useTranslation } from '@payloadcms/ui'
import type {
CustomTranslationsObject,
CustomTranslationsKeys,
} from '../custom-translations'
export const MyComponent: React.FC = () => {
const { i18n, t } = useTranslation<
CustomTranslationsObject,
CustomTranslationsKeys
>() // These generics merge your custom translations with the default client translations
return t('general:myCustomKey')
}
```
Additionally, Payload exposes the `t` function in various places, for example in labels. Here is how you would type those:
```ts
// <rootDir>/fields/myField.ts
import type { TFunction } from '@payloadcms/translations'
import type { Field } from 'payload'
import { CustomTranslationsKeys } from '../custom-translations'
const field: Field = {
name: 'myField',
type: 'text',
label: ({ t: defaultT }) => {
const t = defaultT as TFunction<CustomTranslationsKeys>
return t('fields:addLabel')
},
}
```
# Localization
Source: https://payloadcms.com/docs/configuration/localization
Localization is one of the most important features of a modern CMS. It allows you to manage content in multiple languages, then serve it to your users based on their requested language. This is similar to [I18n](./i18n), but instead of managing translations for your application's interface, you are managing translations for the data itself.
With Localization, you can begin to serve personalized content to your users based on their specific language preferences, such as a multilingual website or multi-site application. There are no limits to the number of locales you can add to your Payload project.
To configure Localization, use the `localization` key in your [Payload Config](./overview):
```ts
import { buildConfig } from 'payload'
export default buildConfig({
// ...
localization: {
// highlight-line
// ...
},
})
```
## Config Options
Add the `localization` property to your Payload Config to enable Localization project-wide. You'll need to provide a list of all locales that you'd like to support as well as set a few other options.
To configure locales, use the `localization.locales` property in your [Payload Config](./overview):
```ts
import { buildConfig } from 'payload'
export default buildConfig({
// ...
localization: {
locales: ['en', 'es', 'de'], // required
defaultLocale: 'en', // required
},
})
```
You can also define locales using [full configuration objects](#locale-object):
```ts
import { buildConfig } from 'payload'
export default buildConfig({
collections: [
// collections go here
],
localization: {
locales: [
{
label: 'English',
code: 'en',
},
{
label: 'Arabic',
code: 'ar',
// opt-in to setting default text-alignment on Input fields to rtl (right-to-left)
// when current locale is rtl
rtl: true,
},
],
defaultLocale: 'en', // required
fallback: true, // defaults to true
},
})
```
<Banner type="success">
**Tip:** Localization works very well alongside
[I18n](../configuration/i18n).
</Banner>
The following options are available:
| Option | Description |
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`locales`** | Array of all the languages that you would like to support. [More details](#locales) |
| **`defaultLocale`** | Required string that matches one of the locale codes from the array provided. By default, if no locale is specified, documents will be returned in this locale. |
| **`fallback`** | Boolean enabling "fallback" locale functionality. If a document is requested in a locale, but a field does not have a localized value corresponding to the requested locale, then if this property is enabled, the document will automatically fall back to the fallback locale value. If this property is not enabled, the value will not be populated unless a fallback is explicitly provided in the request. True by default. |
| **`filterAvailableLocales`** | A function that is called with the array of `locales` and the `req`, it should return locales to show in admin UI selector. [See more](#filter-available-options). |
### Locales
The locales array is a list of all the languages that you would like to support. This can be strings for each language code, or [full configuration objects](#locale-object) for more advanced options.
The locale codes do not need to be in any specific format. It's up to you to define how to represent your locales. Common patterns are to use two-letter ISO 639 language codes or four-letter language and country codes (ISO 3166‑1) such as `en-US`, `en-UK`, `es-MX`, etc.
#### Locale Object
| Option | Description |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| **`code`** \* | Unique code to identify the language throughout the APIs for `locale` and `fallbackLocale` |
| **`label`** | A string to use for the selector when choosing a language, or an object keyed on the i18n keys for different languages in use. |
| **`rtl`** | A boolean that when true will make the admin UI display in Right-To-Left. |
| **`fallbackLocale`** | The code for this language to fallback to when properties of a document are not present. This can be a single locale or array of locales. |
_\* An asterisk denotes that a property is required._
#### Filter Available Options
In some projects you may want to filter the available locales shown in the admin UI selector. You can do this by providing a `filterAvailableLocales` function in your Payload Config. This is called on the server side and is passed the array of locales. This means that you can determine what locales are visible in the localizer selection menu at the top of the admin panel. You could do this per user, or implement a function that scopes these to tenants and more. Here is an example using request headers in a multi-tenant application:
```ts
// ... rest of Payload config
localization: {
defaultLocale: 'en',
locales: ['en', 'es'],
filterAvailableLocales: async ({ req, locales }) => {
if (getTenantFromCookie(req.headers, 'text')) {
const fullTenant = await req.payload.findByID({
id: getTenantFromCookie(req.headers, 'text') as string,
collection: 'tenants',
req,
})
if (fullTenant && fullTenant.supportedLocales?.length) {
return locales.filter((locale) => {
return fullTenant.supportedLocales?.includes(locale.code as 'en' | 'es')
})
}
}
return locales
},
}
```
Since the filtering happens at the root level of the application and its result is not calculated every time you navigate to a new page, you may want to call `router.refresh` in a custom component that watches when values that affect the result change. In the example above, you would want to do this when `supportedLocales` changes on the tenant document.
## Field Localization
Payload Localization works on a **field** level—not a document level. In addition to configuring the base Payload Config to support Localization, you need to specify each field that you would like to localize.
**Here is an example of how to enable Localization for a field:**
```js
{
name: 'title',
type: 'text',
// highlight-start
localized: true,
// highlight-end
}
```
With the above configuration, the `title` field will now be saved in the database as an object of all locales instead of a single string.
All field types with a `name` property support the `localized` property—even the more complex field types like `array`s and `block`s.
<Banner type="info">
**Note:** Enabling Localization for field types that support nested fields
will automatically create localized "sets" of all fields contained within the
field. For example, if you have a page layout using a blocks field type, you
have the choice of either localizing the full layout, by enabling Localization
on the top-level blocks field, or only certain fields within the layout.
</Banner>
<Banner type="warning">
**Important:** When converting an existing field to or from `localized: true`
the data structure in the document will change for this field and so existing
data for this field will be lost. Before changing the Localization setting on
fields with existing data, you may need to consider a field migration
strategy.
</Banner>
## Status Localization
Payload allows you to localize the `status` field for **draft enabled** collections and globals. This lets you manage publication status independently for each locale, ensures the admin UI always shows the status for the selected locale, and unpublish content in a single locale.
<Banner type="warning">
**Important:** This feature is **experimental** and currently in beta, you may
encounter some limitations or bugs. Please test thoroughly before using in
production.
</Banner>
**Two-Step Setup Required:** To enable localized status, you need to set **two** configuration options:
1. Enable the experimental flag in your main config
2. Enable it for specific collections or globals
### Step 1: Enable Experimental Flag
First, enable the experimental flag in your main Payload config:
```ts
import { buildConfig } from 'payload'
export default buildConfig({
// highlight-start
experimental: {
localizeStatus: true, // Required to enable the feature globally
},
// highlight-end
// ... rest of your config
})
```
### Step 2: Enable for Collections/Globals
Then, enable it for specific collections or globals:
```ts
import type { CollectionConfig } from 'payload'
export const Posts: CollectionConfig = {
// ...
versions: {
drafts: {
// highlight-start
localizeStatus: true, // Enable for this specific collection
// highlight-end
},
},
}
```
When enabled, the `status` field will be stored as an object keyed by locales:
```ts
status: {
en: 'published',
es: 'draft',
de: 'published',
}
```
`localizeStatus` is disabled by default, in which case the `status` field returns a single string (`'draft'` or `'published'`) representing the latest document status across all locales.
## Retrieving Localized Docs
When retrieving documents, you can specify which locale you'd like to receive as well as which fallback locale should be
used.
#### REST API
REST API locale functionality relies on URL query parameters.
**`?locale=`**
Specify your desired locale by providing the `locale` query parameter directly in the endpoint URL.
**`?fallback-locale=`**
Specify fallback locale to be used by providing the `fallback-locale` query parameter. This can be provided as either a
valid locale as provided to your base Payload Config, or `'null'`, `'false'`, or `'none'` to disable falling back.
**Example:**
```
fetch('https://localhost:3000/api/pages?locale=es&fallback-locale=none');
```
#### GraphQL API
In the GraphQL API, you can specify `locale` and `fallbackLocale` args to all relevant queries and mutations.
The `locale` arg will only accept valid locales, but locales will be formatted automatically as valid GraphQL enum
values (dashes or special characters will be converted to underscores, spaces will be removed, etc.). If you are curious
to see how locales are auto-formatted, you can use the [GraphQL playground](../graphql/overview#graphql-playground).
The `fallbackLocale` arg will accept valid locales, an array of locales, as well as `none` to disable falling back.
**Example:**
```graphql
query {
Posts(locale: de, fallbackLocale: none) {
docs {
title
}
}
}
```
<Banner>
In GraphQL, specifying the locale at the top level of a query will
automatically apply it throughout all nested relationship fields. You can
override this behavior by re-specifying locale arguments in nested related
document queries.
</Banner>
#### Local API
You can specify `locale` as well as `fallbackLocale` within the Local API as well as properties on the `options`
argument. The `locale` property will accept any valid locale, and the `fallbackLocale` property will accept any valid
locale, array of locales, as well as `'null'`, `'false'`, `false`, and `'none'`.
**Example:**
```js
const posts = await payload.find({
collection: 'posts',
locale: 'es',
fallbackLocale: false,
})
```
<Banner type="success">
**Tip:** The REST and Local APIs can return all Localization data in one
request by passing 'all' or '*' as the **locale** parameter. The response will
be structured so that field values come back as the full objects keyed for
each locale instead of the single, translated value.
</Banner>
# Environment Variables
Source: https://payloadcms.com/docs/configuration/environment-vars
Environment Variables are a way to store sensitive information that your application needs to function. This could be anything from API keys to [Database](../database/overview) credentials. Payload allows you to easily use Environment Variables within your config and throughout your application.
## Next.js Applications
If you are using Next.js, no additional setup is required other than creating your `.env` file.
To use Environment Variables, add a `.env` file to the root of your project:
```plaintext
project-name/
├─ .env
├─ package.json
├─ payload.config.ts
```
Here is an example of what an `.env` file might look like:
```plaintext
SERVER_URL=localhost:3000
DATABASE_URL=mongodb://localhost:27017/my-database
```
To use Environment Variables in your Payload Config, you can access them directly from `process.env`:
```ts
import { buildConfig } from 'payload'
export default buildConfig({
serverURL: process.env.SERVER_URL, // highlight-line
// ...
})
```
## Client-side Environments
For security and safety reasons, the [Admin Panel](../admin/overview) does **not** include Environment Variables in its _client-side_ bundle by default. But, Next.js provides a mechanism to expose Environment Variables to the client-side bundle when needed.
If you are building a [Custom Component](../custom-components/overview) and need to access Environment Variables from the client-side, you can do so by prefixing them with `NEXT_PUBLIC_`.
<Banner type="warning">
**Important:** Be careful about what variables you provide to your client-side
code. Analyze every single one to make sure that you're not accidentally
leaking sensitive information. Only ever include keys that are safe for the
public to read in plain text.
</Banner>
For example, if you've got the following Environment Variable:
```bash
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_XXXXXXXXXXXXXXXXXX
```
This key will automatically be made available to the client-side Payload bundle and can be referenced in your Custom Component as follows:
```tsx
'use client'
import React from 'react'
const stripeKey = process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY // highlight-line
const MyClientComponent = () => {
// do something with the key
return <div>My Client Component</div>
}
```
For more information, check out the [Next.js documentation](https://nextjs.org/docs/app/building-your-application/configuring/environment-variables).
## Outside of Next.js
If you are using Payload outside of Next.js, we suggest using the [`dotenv`](https://www.npmjs.com/package/dotenv) package to handle Environment Variables from `.env` files. This will automatically load your Environment Variables into `process.env`.
To do this, import the package as high up in your application as possible:
```ts
import dotenv from 'dotenv'
dotenv.config() // highlight-line
import { buildConfig } from 'payload'
export default buildConfig({
serverURL: process.env.SERVER_URL,
// ...
})
```
<Banner type="warning">
**Tip:** Be sure that `dotenv` can find your `.env` file. By default, it will
look for a file named `.env` in the root of your project. If you need to
specify a different file, pass the path into the config options.
</Banner>
# Database
Source: https://payloadcms.com/docs/database/overview
Payload is database agnostic, meaning you can use any type of database behind Payload's familiar APIs. Payload is designed to interact with your database through a Database Adapter, which is a thin layer that translates Payload's internal data structures into your database's native data structures.
Currently, Payload officially supports the following Database Adapters:
- [MongoDB](../database/mongodb) with [Mongoose](https://mongoosejs.com/)
- [Postgres](../database/postgres) with [Drizzle](https://drizzle.team/)
- [SQLite](../database/sqlite) with [Drizzle](https://drizzle.team/)
To configure a Database Adapter, use the `db` property in your [Payload Config](../configuration/overview):
```ts
import { buildConfig } from 'payload'
import { mongooseAdapter } from '@payloadcms/db-mongodb'
export default buildConfig({
// ...
// highlight-start
db: mongooseAdapter({
url: process.env.DATABASE_URL,
}),
// highlight-end
})
```
<Banner type="warning">
**Reminder:** The Database Adapter is an external dependency and must be
installed in your project separately from Payload. You can find the
installation instructions for each Database Adapter in their respective
documentation.
</Banner>
## Selecting a Database
There are several factors to consider when choosing which database technology and hosting option is right for your project and workload. Payload can theoretically support any database, but it's up to you to decide which database to use.
There are two main categories of databases to choose from:
- [Non-Relational Databases](#non-relational-databases)
- [Relational Databases](#relational-databases)
### Non-Relational Databases
If your project has a lot of dynamic fields, and you are comfortable with allowing Payload to enforce data integrity across your documents, MongoDB is a great choice. With it, your Payload documents are stored as _one_ document in your database—no matter if you have localization enabled, how many block or array fields you have, etc. This means that the shape of your data in your database will very closely reflect your field schema, and there is minimal complexity involved in storing or retrieving your data.
You should prefer MongoDB if:
- You prefer simplicity within your database
- You don't want to deal with keeping production / staging databases in sync via [DDL changes](https://en.wikipedia.org/wiki/Data_definition_language)
- Most (or everything) in your project is [Localized](../configuration/localization)
- You leverage a lot of [Arrays](../fields/array), [Blocks](../fields/blocks), or `hasMany` [Select](../fields/select) fields
### Relational Databases
Many projects might call for more rigid database architecture where the shape of your data is strongly enforced at the database level. For example, if you know the shape of your data and it's relatively "flat", and you don't anticipate it to change often, your workload might suit relational databases like Postgres very well.
You should prefer a relational DB like Postgres or SQLite if:
- You are comfortable with [Migrations](./migrations)
- You require enforced data consistency at the database level
- You have a lot of relationships between collections and require relationships to be enforced
## Payload Differences
It's important to note that nearly every Payload feature is available in all of our officially supported Database Adapters, including [Localization](../configuration/localization), [Arrays](../fields/array), [Blocks](../fields/blocks), etc. The only thing that is not supported in SQLite yet is the [Point Field](../fields/point), but that should be added soon.
It's up to you to choose which database you would like to use based on the requirements of your project. Payload has no opinion on which database you should ultimately choose.
# Migrations
Source: https://payloadcms.com/docs/database/migrations
Payload exposes a full suite of migration controls available for your use. Migration commands are accessible via
the `npm run payload` command in your project directory.
Ensure you have an npm script called "payload" in your `package.json` file.
```json
{
"scripts": {
"payload": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts payload"
}
}
```
<Banner>
Note that you need to run Payload migrations through the package manager that
you are using, because Payload should not be globally installed on your
system.
</Banner>
## Migration file contents
Payload stores all created migrations in a folder that you can specify. By default, migrations are stored
in `./src/migrations`.
A migration file has two exports - an `up` function, which is called when a migration is executed, and a `down` function
that will be called if for some reason the migration fails to complete successfully. The `up` function should contain
all changes that you attempt to make within the migration, and the `down` should ideally revert any changes you make.
Here is an example migration file:
```ts
import { MigrateUpArgs, MigrateDownArgs } from '@payloadcms/your-db-adapter'
export async function up({ payload, req }: MigrateUpArgs): Promise<void> {
// Perform changes to your database here.
// You have access to `payload` as an argument, and
// everything is done in TypeScript.
}
export async function down({ payload, req }: MigrateDownArgs): Promise<void> {
// Do whatever you need to revert changes if the `up` function fails
}
```
## Using Transactions
When migrations are run, each migration is performed in a new [transaction](../database/transactions) for you. All
you need to do is pass the `req` object to any [Local API](../local-api/overview) or direct database calls, such as
`payload.db.updateMany()`, to make database changes inside the transaction. Assuming no errors were thrown, the transaction is committed
after your `up` or `down` function runs. If the migration errors at any point or fails to commit, it is caught and the
transaction gets aborted. This way no change is made to the database if the migration fails.
### Using database directly with the transaction
Additionally, you can bypass Payload's layer entirely and perform operations directly on your underlying database within the active transaction:
### MongoDB:
```ts
import { type MigrateUpArgs } from '@payloadcms/db-mongodb'
export async function up({
session,
payload,
req,
}: MigrateUpArgs): Promise<void> {
const posts = await payload.db.collections.posts.collection
.find({ session })
.toArray()
}
```
### Postgres:
```ts
import { type MigrateUpArgs, sql } from '@payloadcms/db-postgres'
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
const { rows: posts } = await db.execute(sql`SELECT * from posts`)
}
```
### SQLite:
In SQLite, transactions are disabled by default. [More](./transactions).
```ts
import { type MigrateUpArgs, sql } from '@payloadcms/db-sqlite'
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
const { rows: posts } = await db.run(sql`SELECT * from posts`)
}
```
## Migrations Directory
Each DB adapter has an optional property `migrationDir` where you can override where you want your migrations to be
stored/read. If this is not specified, Payload will check the default and possibly make a best effort to find your
migrations directory by searching in common locations ie. `./src/migrations`, `./dist/migrations`, `./migrations`, etc.
All database adapters should implement similar migration patterns, but there will be small differences based on the
adapter and its specific needs. Below is a list of all migration commands that should be supported by your database
adapter.
## Commands
### Migrate
The `migrate` command will run any migrations that have not yet been run.
```text
npm run payload migrate
```
### Create
Create a new migration file in the migrations directory. You can optionally name the migration that will be created. By
default, migrations will be named using a timestamp.
```text
npm run payload migrate:create optional-name-here
```
Flags:
- `--skip-empty`: with Postgres, it skips the "no schema changes detected. Would you like to create a blank migration file?" prompt which can be useful for generating migration in CI.
- `--force-accept-warning`: accepts any command prompts, creates a blank migration even if there weren't any changes to the schema.
### Status
The `migrate:status` command will check the status of migrations and output a table of which migrations have been run,
and which migrations have not yet run.
`payload migrate:status`
```text
npm run payload migrate:status
```
### Down
Roll back the last batch of migrations.
```text
npm run payload migrate:down
```
### Refresh
Roll back all migrations that have been run, and run them again.
```text
npm run payload migrate:refresh
```
### Reset
Roll back all migrations.
```text
npm run payload migrate:reset
```
### Fresh
Drops all entities from the database and re-runs all migrations from scratch.
```text
npm run payload migrate:fresh
```
## When to run migrations
Depending on which Database Adapter you use, your migration workflow might differ subtly.
In relational databases, migrations will be **required** for non-development database environments. But with MongoDB, you might only need to run migrations once in a while (or never even need them).
#### MongoDB#mongodb-migrations
In MongoDB, you'll only ever really need to run migrations for times where you change your database shape, and you have lots of existing data that you'd like to transform from Shape A to Shape B.
In this case, you can create a migration by running `pnpm payload migrate:create`, and then write the logic that you need to perform to migrate your documents to their new shape. You can then either run your migrations in CI before you build / deploy, or you can run them locally, against your production database, by using your production database connection string on your local computer and running the `pnpm payload migrate` command.
#### Postgres#postgres-migrations
In relational databases like Postgres, migrations are a bit more important, because each time you add a new field or a new collection, you'll need to update the shape of your database to match your Payload Config (otherwise you'll see errors upon trying to read / write your data).
That means that Postgres users of Payload should become familiar with the entire migration workflow from top to bottom.
Here is an overview of a common workflow for working locally against a development database, creating migrations, and then running migrations against your production database before deploying.
**1 - work locally using push mode**
Payload uses Drizzle ORM's powerful `push` mode to automatically sync data changes to your database for you while in development mode. By default, this is enabled and is the suggested workflow to using Postgres and Payload while doing local development.
You can disable this setting and solely use migrations to manage your local development database (pass `push: false` to your Postgres adapter), but if you do disable it, you may see frequent errors while running development mode. This is because Payload will have updated to your new data shape, but your local database will not have updated.
For this reason, we suggest that you leave `push` as its default setting and treat your local dev database as a sandbox.
For more information about push mode and prototyping in development, [click here](./postgres#prototyping-in-development-mode).
The typical workflow in Payload is to build out your Payload configs, install plugins, and make progress in development mode - allowing Drizzle to push your changes to your local database for you. Once you're finished, you can create a migration.
But importantly, you do not need to run migrations against your development database, because Drizzle will have already pushed your changes to your database for you.
<Banner type="warning">
Warning: do not mix "push" and migrations with your local development
database. If you use "push" locally, and then try to migrate, Payload will
throw a warning, telling you that these two methods are not meant to be used
interchangeably.
</Banner>
**2 - create a migration**
Once you're done with working in your Payload Config, you can create a migration. It's best practice to try and complete a specific task or fully build out a feature before you create a migration.
But once you're ready, you can run `pnpm payload migrate:create`, which will perform the following steps for you:
- We will look for any existing migrations, and automatically generate SQL changes necessary to convert your schema from its prior state to the new state of your Payload Config
- We will then create a new migration file in your `/migrations` folder that contains all the SQL necessary to be run
We won't immediately run this migration for you, however.
<Banner type="success">
Tip: migrations created by Payload are relatively programmatic in nature, so
there should not be any surprises, but before you check in the created
migration it's a good idea to always double-check the contents of the
migration files.
</Banner>
**3 - set up your build process to run migrations**
Generally, you want to run migrations before you build Payload for production. This typically happens in your CI pipeline and can usually be configured on platforms like Payload Cloud, Vercel, or Netlify by specifying your build script.
A common set of scripts in a `package.json`, set up to run migrations in CI, might look like this:
```js
"scripts": {
// For running in dev mode
"dev": "next dev --turbo",
// To build your Next + Payload app for production
"build": "next build",
// A "tie-in" to Payload's CLI for convenience
// this helps you run `pnpm payload migrate:create` and similar
"payload": "cross-env NODE_OPTIONS=--no-deprecation payload",
// This command is what you'd set your `build script` to.
// Notice how it runs `payload migrate` and then `pnpm build`?
// This will run all migrations for you before building, in your CI,
// against your production database
"ci": "payload migrate && pnpm build",
},
```
In the example above, we've specified a `ci` script which we can use as our "build script" in the platform that we are deploying to production with.
This will require that your build pipeline can connect to your database, and it will simply run the `payload migrate` command prior to starting the build process. By calling `payload migrate`, Payload will automatically execute any migrations in your `/migrations` folder that have not yet been executed against your production database, in the order that they were created.
If it fails, the deployment will be rejected. But now, with your build script set up to run your migrations, you will be all set! Next time you deploy, your CI will execute the required migrations for you, and your database will be caught up with the shape that your Payload Config requires.
## Running migrations in production
In certain cases, you might want to run migrations at runtime when the server starts. Running them during build time may be impossible due to not having access to your database connection while building or similar reasoning.
If you're using a long-running server or container where your Node server starts up one time and then stays initialized, you might prefer to run migrations on server startup instead of within your CI.
In order to run migrations at runtime, on initialization, you can pass your migrations to your database adapter under the `prodMigrations` key as follows:
```ts
// Import your migrations from the `index.ts` file
// that Payload generates for you
import { migrations } from './migrations'
import { buildConfig } from 'payload'
export default buildConfig({
// your config here
db: postgresAdapter({
// your adapter config here
prodMigrations: migrations,
}),
})
```
Passing your migrations as shown above will tell Payload, in production only, to execute any migrations that need to be run prior to completing the initialization of Payload. This is ideal for long-running services where Payload will only be initialized at startup.
<Banner type="warning">
**Warning:** if Payload is instructed to run migrations in production, this
may slow down serverless cold starts on platforms such as Vercel. Generally,
this option should only be used for long-running servers / containers.
</Banner>
## Environment-Specific Configurations and Migrations
Your configuration may include environment-specific settings (e.g., enabling a plugin only in production). If you generate migrations without considering the environment, it can lead to discrepancies and issues. When running migrations locally, Payload uses the development environment, which might miss production-specific configurations. Similarly, running migrations in production could miss development-specific entities.
This is an easy oversight, so be mindful of any environment-specific logic in your config when handling migrations.
**Ways to address this:**
- Manually update your migration file after it is generated to include any environment-specific configurations.
- Temporarily enable any required production environment variables in your local setup when generating the migration to capture the necessary updates.
- Use separate migration files for each environment to ensure the correct migration is executed in the corresponding environment.
# Transactions
Source: https://payloadcms.com/docs/database/transactions
Database transactions allow your application to make a series of database changes in an all-or-nothing commit. Consider an HTTP request that creates a new **Order** and has an `afterChange` hook to update the stock count of related **Items**. If an error occurs when updating an **Item** and an HTTP error is returned to the user, you would not want the new **Order** to be persisted or any other items to be changed either. This kind of interaction with the database is handled seamlessly with transactions.
By default, Payload will use transactions for all data changing operations, as long as it is supported by the configured database. Database changes are contained within all Payload operations and any errors thrown will result in all changes being rolled back without being committed. When transactions are not supported by the database, Payload will continue to operate as expected without them.
<Banner type="info">
**Note:**
MongoDB requires a connection to a replicaset in order to make use of transactions.
</Banner>
<Banner type="info">
**Note:**
Transactions in SQLite are disabled by default. You need to pass `transactionOptions: {}` to enable them.
</Banner>
The initial request made to Payload will begin a new transaction and attach it to the `req.transactionID`. If you have a `hook` that interacts with the database, you can opt in to using the same transaction by passing the `req` in the arguments. For example:
```ts
const afterChange: CollectionAfterChangeHook = async ({ req }) => {
// because req.transactionID is assigned from Payload and passed through,
// my-slug will only persist if the entire request is successful
await req.payload.create({
req,
collection: 'my-slug',
data: {
some: 'data',
},
})
}
```
## Async Hooks with Transactions
Since Payload hooks can be async and be written to not await the result, it is possible to have an incorrect success response returned on a request that is rolled back. If you have a hook where you do not `await` the result, then you should **not** pass the `req.transactionID`.
```ts
const afterChange: CollectionAfterChangeHook = async ({ req }) => {
// WARNING: an async call made with the same req, but NOT awaited,
// may fail resulting in an OK response being returned with response data that is not committed
const dangerouslyIgnoreAsync = req.payload.create({
req,
collection: 'my-slug',
data: {
some: 'other data',
},
})
// Should this call fail, it will not rollback other changes
// because the req (and its transactionID) is not passed through
const safelyIgnoredAsync = req.payload.create({
collection: 'my-slug',
data: {
some: 'other data',
},
})
}
```
## Direct Transaction Access
When writing your own scripts or custom endpoints, you may wish to have direct control over transactions. This is useful for interacting with your database outside of Payload's Local API.
The following functions can be used for managing transactions:
- `payload.db.beginTransaction` - Starts a new session and returns a transaction ID for use in other Payload Local API calls.
- `payload.db.commitTransaction` - Takes the identifier for the transaction, finalizes any changes.
- `payload.db.rollbackTransaction` - Takes the identifier for the transaction, discards any changes.
Payload uses the `req` object to pass the transaction ID through to the database adapter. If you are not using the `req` object, you can make a new object to pass the transaction ID directly to database adapter methods and Local API calls.
Example:
```ts
import payload from 'payload'
import config from './payload.config'
const standalonePayloadScript = async () => {
// initialize Payload
await payload.init({ config })
const transactionID = await payload.db.beginTransaction()
try {
// Make an update using the Local API
await payload.update({
collection: 'posts',
data: {
some: 'data',
},
where: {
slug: { equals: 'my-slug' },
},
req: { transactionID },
})
/*
You can make additional db changes or run other functions
that need to be committed on an all or nothing basis
*/
// Commit the transaction
await payload.db.commitTransaction(transactionID)
} catch (error) {
// Rollback the transaction
await payload.db.rollbackTransaction(transactionID)
}
}
standalonePayloadScript()
```
## Disabling Transactions
If you wish to disable transactions entirely, you can do so by passing `false` as the `transactionOptions` in your database adapter configuration. All the official Payload database adapters support this option.
In addition to allowing database transactions to be disabled at the adapter level. You can prevent Payload from using a transaction in direct calls to the Local API by adding `disableTransaction: true` to the args. For example:
```ts
await payload.update({
collection: 'posts',
data: {
some: 'data',
},
where: {
slug: { equals: 'my-slug' },
},
disableTransaction: true,
})
```
# Indexes
Source: https://payloadcms.com/docs/database/indexes
Database indexes are a way to optimize the performance of your database by allowing it to quickly locate and retrieve data. If you have a field that you frequently query or sort by, adding an index to that field can significantly improve the speed of those operations.
When your query runs, the database will not scan the entire document to find that one field, but will instead use the index to quickly locate the data.
To index a field, set the `index` option to `true` in your field's config:
```ts
import type { CollectionConfig } from 'payload'
export const MyCollection: CollectionConfig = {
// ...
fields: [
// ...
{
name: 'title',
type: 'text',
// highlight-start
index: true,
// highlight-end
},
],
}
```
<Banner type="info">
**Note:** The `id`, `createdAt`, and `updatedAt` fields are indexed by
default.
</Banner>
<Banner type="success">
**Tip:** If you're using MongoDB, you can use [MongoDB
Compass](https://www.mongodb.com/products/compass) to visualize and manage
your indexes.
</Banner>
## Compound Indexes
In addition to indexing single fields, you can also create compound indexes that index multiple fields together. This can be useful for optimizing queries that filter or sort by multiple fields.
To create a compound index, use the `indexes` option in your [Collection Config](../configuration/collections):
```ts
import type { CollectionConfig } from 'payload'
export const MyCollection: CollectionConfig = {
// ...
fields: [
// ...
],
indexes: [
{
fields: ['title', 'createdAt'],
unique: true, // Optional, if you want the combination of fields to be unique
},
],
}
```
## Localized fields and MongoDB indexes
When you set `index: true` or `unique: true` on a localized field, MongoDB creates one index **per locale path** (e.g., `slug.en`, `slug.da-dk`, etc.). With many locales and indexed fields, this can quickly approach MongoDB's per-collection index limit.
If you know you'll query specifically by a locale, you can insert a custom MongoDB index for the locale path manually or with a migration script.
# MongoDB
Source: https://payloadcms.com/docs/database/mongodb
To use Payload with MongoDB, install the package `@payloadcms/db-mongodb`. It will come with everything you need to
store your Payload data in MongoDB.
Then from there, pass it to your Payload Config as follows:
```ts
import { mongooseAdapter } from '@payloadcms/db-mongodb'
export default buildConfig({
// Your config goes here
collections: [
// Collections go here
],
// Configure the Mongoose adapter here
db: mongooseAdapter({
// Mongoose-specific arguments go here.
// URL is required.
url: process.env.DATABASE_URL,
}),
})
```
## Options
| Option | Description |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `autoPluralization` | Tell Mongoose to auto-pluralize any collection names if it encounters any singular words used as collection `slug`s. |
| `bulkOperationsSingleTransaction` | When `true`, bulk update and delete operations will process documents one at a time in separate transactions instead of all at once in a single transaction. Useful for avoiding transaction limitations with large datasets in DocumentDB and Cosmos DB. Defaults to `false`. |
| `connectOptions` | Customize MongoDB connection options. Payload will connect to your MongoDB database using default options which you can override and extend to include all the [options](https://mongoosejs.com/docs/connections.html#options) available to mongoose. |
| `collectionsSchemaOptions` | Customize Mongoose schema options for collections. |
| `disableIndexHints` | Set to true to disable hinting to MongoDB to use 'id' as index. This is currently done when counting documents for pagination, as it increases the speed of the count function used in that query. Disabling this optimization might fix some problems with AWS DocumentDB. Defaults to false |
| `migrationDir` | Customize the directory that migrations are stored. |
| `transactionOptions` | An object with configuration properties used in [transactions](https://www.mongodb.com/docs/manual/core/transactions/) or `false` which will disable the use of transactions. |
| `collation` | Enable language-specific string comparison with customizable options. Available on MongoDB 3.4+. Defaults locale to "en". Example: `{ strength: 3 }`. For a full list of collation options and their definitions, see the [MongoDB documentation](https://www.mongodb.com/docs/manual/reference/collation/). |
| `allowAdditionalKeys` | By default, Payload strips all additional keys from MongoDB data that don't exist in the Payload schema. If you have some data that you want to include to the result but it doesn't exist in Payload, you can set this to `true`. Be careful as Payload access control _won't_ work for this data. |
| `allowIDOnCreate` | Set to `true` to use the `id` passed in data on the create API operations without using a custom ID field. |
| `disableFallbackSort` | Set to `true` to disable the adapter adding a fallback sort when sorting by non-unique fields, this can affect performance in some cases but it ensures a consistent order of results. |
| `useAlternativeDropDatabase` | Set to `true` to use an alternative `dropDatabase` implementation that calls `collection.deleteMany({})` on every collection instead of sending a raw `dropDatabase` command. Payload only uses `dropDatabase` for testing purposes. Defaults to `false`. |
| `useBigIntForNumberIDs` | Set to `true` to use `BigInt` for custom ID fields of type `'number'`. Useful for databases that don't support `double` or `int32` IDs. Defaults to `false`. |
| `useJoinAggregations` | Set to `false` to disable join aggregations (which use correlated subqueries) and instead populate join fields via multiple `find` queries. Defaults to `true`. |
| `usePipelineInSortLookup` | Set to `false` to disable the use of `pipeline` in the `$lookup` aggregation in sorting. Defaults to `true`. |
## Access to Mongoose models
After Payload is initialized, this adapter exposes all of your Mongoose models and they are available for you to work
with directly.
You can access Mongoose models as follows:
- Collection models - `payload.db.collections[myCollectionSlug]`
- Globals model - `payload.db.globals`
- Versions model (both collections and globals) - `payload.db.versions[myEntitySlug]`
## Using other MongoDB implementations
You can import the `compatibilityOptions` object to get the recommended settings for other MongoDB implementations. Since these databases aren't officially supported by payload, you may still encounter issues even with these settings (please create an issue or PR if you believe these options should be updated):
```ts
import { mongooseAdapter, compatibilityOptions } from '@payloadcms/db-mongodb'
export default buildConfig({
db: mongooseAdapter({
url: process.env.DATABASE_URL,
// For example, if you're using firestore:
...compatibilityOptions.firestore,
}),
})
```
We export compatibility options for [DocumentDB](https://aws.amazon.com/documentdb/), [Azure Cosmos DB](https://azure.microsoft.com/en-us/products/cosmos-db) and [Firestore](https://cloud.google.com/firestore/mongodb-compatibility/docs/overview). Known limitations:
- Azure Cosmos DB does not support transactions that update two or more documents in different collections, which is a common case when using Payload (via hooks).
- Azure Cosmos DB requires the root config property `indexSortableFields` to be set to `true`.
## Using collation
There are situations where you may want to use language-specific string comparison, for example when sorting strings with accents or in different languages. MongoDB supports this via [collation](https://www.mongodb.com/docs/manual/reference/collation/).
We thread your locale automatically through to the MongoDB queries when collation is enabled in the adapter, so that when you sort by a field, it uses the correct language rules for that locale.
To enable collation, set the `collation` option in the adapter configuration:
```ts
import { mongooseAdapter } from '@payloadcms/db-mongodb'
export default buildConfig({
// Your config goes here
collections: [
// Collections go here
],
// Configure the Mongoose adapter here
db: mongooseAdapter({
// Mongoose-specific arguments go here.
// URL is required.
url: process.env.DATABASE_URL,
collation: {
// Set any MongoDB collation options here.
// The locale will be set automatically based on the request locale.
strength: 1, // Example option
},
}),
})
```
<Banner type="warning">
Collation will affect things like sort based on the locale being used. Please
test thoroughly before using in production as it can affect your queries.
</Banner>
# Postgres
Source: https://payloadcms.com/docs/database/postgres
To use Payload with Postgres, install the package `@payloadcms/db-postgres`. It leverages Drizzle ORM and `node-postgres` to interact with a Postgres database that you provide.
Alternatively, the `@payloadcms/db-vercel-postgres` package is also available and is optimized for use with Vercel.
It automatically manages changes to your database for you in development mode, and exposes a full suite of migration controls for you to leverage in order to keep other database environments in sync with your schema. DDL transformations are automatically generated.
To configure Payload to use Postgres, pass the `postgresAdapter` to your Payload Config as follows:
### Usage
`@payloadcms/db-postgres`:
```ts
import { postgresAdapter } from '@payloadcms/db-postgres'
export default buildConfig({
// Configure the Postgres adapter here
db: postgresAdapter({
// Postgres-specific arguments go here.
// `pool` is required.
pool: {
connectionString: process.env.DATABASE_URL,
},
}),
})
```
`@payloadcms/db-vercel-postgres`:
```ts
import { vercelPostgresAdapter } from '@payloadcms/db-vercel-postgres'
export default buildConfig({
// Automatically uses process.env.POSTGRES_URL if no options are provided.
db: vercelPostgresAdapter(),
// Optionally, can accept the same options as the @vercel/postgres package.
db: vercelPostgresAdapter({
pool: {
connectionString: process.env.DATABASE_URL,
},
}),
})
```
<Banner type="info">
**Note:** If you're using `vercelPostgresAdapter` and your
`process.env.POSTGRES_URL` or `pool.connectionString` points to a local
database (e.g hostname has `localhost` or `127.0.0.1`) we use the `pg` module
for pooling instead of `@vercel/postgres`. This is because `@vercel/postgres`
doesn't work with local databases, if you want to disable that behavior, you
can pass `forceUseVercelPostgres: true` to the adapter's args and follow
[Vercel
guide](https://vercel.com/docs/storage/vercel-postgres/local-development#option-2:-local-postgres-instance-with-docker)
for a Docker Neon DB setup.
</Banner>
## Options
| Option | Description |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pool` \* | [Pool connection options](https://orm.drizzle.team/docs/quick-postgresql/node-postgres) that will be passed to Drizzle and `node-postgres` or to `@vercel/postgres` |
| `push` | Disable Drizzle's [`db push`](https://orm.drizzle.team/kit-docs/overview#prototyping-with-db-push) in development mode. By default, `push` is enabled for development mode only. |
| `migrationDir` | Customize the directory that migrations are stored. |
| `schemaName` (experimental) | A string for the postgres schema to use, defaults to 'public'. |
| `idType` | A string of 'serial', or 'uuid' that is used for the data type given to id columns. |
| `transactionOptions` | A PgTransactionConfig object for transactions, or set to `false` to disable using transactions. [More details](https://orm.drizzle.team/docs/transactions) |
| `disableCreateDatabase` | Pass `true` to disable auto database creation if it doesn't exist. Defaults to `false`. |
| `localesSuffix` | A string appended to the end of table names for storing localized fields. Default is '\_locales'. |
| `relationshipsSuffix` | A string appended to the end of table names for storing relationships. Default is '\_rels'. |
| `versionsSuffix` | A string appended to the end of table names for storing versions. Defaults to '\_v'. |
| `beforeSchemaInit` | Drizzle schema hook. Runs before the schema is built. [More Details](#beforeschemainit) |
| `afterSchemaInit` | Drizzle schema hook. Runs after the schema is built. [More Details](#afterschemainit) |
| `generateSchemaOutputFile` | Override generated schema from `payload generate:db-schema` file path. Defaults to `{CWD}/src/payload-generated.schema.ts` |
| `allowIDOnCreate` | Set to `true` to use the `id` passed in data on the create API operations without using a custom ID field. |
| `readReplicas` | An array of DB read replicas connection strings, can be used to offload read-heavy traffic. |
| `blocksAsJSON` | Store blocks as a JSON column instead of using the relational structure which can improve performance with a large amount of blocks |
## Access to Drizzle
After Payload is initialized, this adapter will expose the full power of Drizzle to you for use if you need it.
To ensure type-safety, you need to generate Drizzle schema first with:
```sh
npx payload generate:db-schema
```
Then, you can access Drizzle as follows:
```ts
import { posts } from './payload-generated-schema'
// To avoid installing Drizzle, you can import everything that drizzle has from our re-export path.
import { eq, sql, and } from '@payloadcms/db-postgres/drizzle'
// Drizzle's Querying API: https://orm.drizzle.team/docs/rqb
const posts = await payload.db.drizzle.query.posts.findMany()
// Drizzle's Select API https://orm.drizzle.team/docs/select
const result = await payload.db.drizzle
.select()
.from(posts)
.where(
and(eq(posts.id, 50), sql`lower(${posts.title}) = 'example post title'`),
)
```
## Tables, relations, and enums
In addition to exposing Drizzle directly, all of the tables, Drizzle relations, and enum configs are exposed for you via the `payload.db` property as well.
- Tables - `payload.db.tables`
- Enums - `payload.db.enums`
- Relations - `payload.db.relations`
## Prototyping in development mode
Drizzle exposes two ways to work locally in development mode.
The first is [`db push`](https://orm.drizzle.team/kit-docs/overview#prototyping-with-db-push), which automatically pushes changes you make to your Payload Config (and therefore, Drizzle schema) to your database so you don't have to manually migrate every time you change your Payload Config. This only works in development mode, and should not be mixed with manually running [`migrate`](../database/migrations) commands.
You will be warned if any changes that you make will entail data loss while in development mode. Push is enabled by default, but you can opt out if you'd like.
Alternatively, you can disable `push` and rely solely on migrations to keep your local database in sync with your Payload Config.
## Migration workflows
In Postgres, migrations are a fundamental aspect of working with Payload and you should become familiar with how they work.
For more information about migrations, [click here](./migrations#when-to-run-migrations).
## Drizzle schema hooks
### beforeSchemaInit
Runs before the schema is built. You can use this hook to extend your database structure with tables that won't be managed by Payload.
```ts
import { postgresAdapter } from '@payloadcms/db-postgres'
import {
integer,
pgTable,
serial,
} from '@payloadcms/db-postgres/drizzle/pg-core'
postgresAdapter({
beforeSchemaInit: [
({ schema, adapter }) => {
return {
...schema,
tables: {
...schema.tables,
addedTable: pgTable('added_table', {
id: serial('id').notNull(),
}),
},
}
},
],
})
```
One use case is preserving your existing database structure when migrating to Payload. By default, Payload drops the current database schema, which may not be desirable in this scenario.
To quickly generate the Drizzle schema from your database you can use [Drizzle Introspection](https://orm.drizzle.team/kit-docs/commands#introspect--pull)
You should get the `schema.ts` file which may look like this:
```ts
import {
pgTable,
uniqueIndex,
serial,
varchar,
text,
} from 'drizzle-orm/pg-core'
export const users = pgTable('users', {
id: serial('id').primaryKey(),
fullName: text('full_name'),
phone: varchar('phone', { length: 256 }),
})
export const countries = pgTable(
'countries',
{
id: serial('id').primaryKey(),
name: varchar('name', { length: 256 }),
},
(countries) => {
return {
nameIndex: uniqueIndex('name_idx').on(countries.name),
}
},
)
```
You can import them into your config and append to the schema with the `beforeSchemaInit` hook like this:
```ts
import { postgresAdapter } from '@payloadcms/db-postgres'
import { users, countries } from '../drizzle/schema'
postgresAdapter({
beforeSchemaInit: [
({ schema, adapter }) => {
return {
...schema,
tables: {
...schema.tables,
users,
countries,
},
}
},
],
})
```
Make sure Payload doesn't overlap table names with its collections. For example, if you already have a collection with slug "users", you should either change the slug or `dbName` to change the table name for this collection.
### afterSchemaInit
Runs after the Drizzle schema is built. You can use this hook to modify the schema with features that aren't supported by Payload, or if you want to add a column that you don't want to be in the Payload config.
To extend a table, Payload exposes `extendTable` utility to the args. You can refer to the [Drizzle documentation](https://orm.drizzle.team/docs/sql-schema-declaration).
The following example adds the `extra_integer_column` column and a composite index on `country` and `city` columns.
```ts
import { postgresAdapter } from '@payloadcms/db-postgres'
import { index, integer } from '@payloadcms/db-postgres/drizzle/pg-core'
import { buildConfig } from 'payload'
export default buildConfig({
collections: [
{
slug: 'places',
fields: [
{
name: 'country',
type: 'text',
},
{
name: 'city',
type: 'text',
},
],
},
],
db: postgresAdapter({
afterSchemaInit: [
({ schema, extendTable, adapter }) => {
extendTable({
table: schema.tables.places,
columns: {
extraIntegerColumn: integer('extra_integer_column'),
},
extraConfig: (table) => ({
country_city_composite_index: index(
'country_city_composite_index',
).on(table.country, table.city),
}),
})
return schema
},
],
}),
})
```
### Note for generated schema:
Columns and tables, added in schema hooks won't be added to the generated via `payload generate:db-schema` Drizzle schema.
If you want them to be there, you either have to edit this file manually or mutate the internal Payload "raw" SQL schema in the `beforeSchemaInit`:
```ts
import { postgresAdapter } from '@payloadcms/db-postgres'
postgresAdapter({
beforeSchemaInit: [
({ schema, adapter }) => {
// Add a new table
adapter.rawTables.myTable = {
name: 'my_table',
columns: {
my_id: {
name: 'my_id',
type: 'serial',
primaryKey: true,
},
},
}
// Add a new column to generated by Payload table:
adapter.rawTables.posts.columns.customColumn = {
name: 'custom_column',
// Note that Payload SQL doesn't support everything that Drizzle does.
type: 'integer',
notNull: true,
}
// Add a new index to generated by Payload table:
adapter.rawTables.posts.indexes.customColumnIdx = {
name: 'custom_column_idx',
unique: true,
on: ['custom_column'],
}
return schema
},
],
})
```
# SQLite
Source: https://payloadcms.com/docs/database/sqlite
To use Payload with SQLite, install the package `@payloadcms/db-sqlite`. It leverages Drizzle ORM and `libSQL` to interact with a SQLite database that you provide.
It automatically manages changes to your database for you in development mode, and exposes a full suite of migration controls for you to leverage in order to keep other database environments in sync with your schema. DDL transformations are automatically generated.
To configure Payload to use SQLite, pass the `sqliteAdapter` to your Payload Config as follows:
```ts
import { sqliteAdapter } from '@payloadcms/db-sqlite'
export default buildConfig({
// Your config goes here
collections: [
// Collections go here
],
// Configure the SQLite adapter here
db: sqliteAdapter({
// SQLite-specific arguments go here.
// `client.url` is required.
client: {
url: process.env.DATABASE_URL,
authToken: process.env.DATABASE_AUTH_TOKEN,
},
}),
})
```
## Options
| Option | Description |
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `client` \* | [Client connection options](https://orm.drizzle.team/docs/get-started-sqlite#turso) that will be passed to `createClient` from `@libsql/client`. |
| `push` | Disable Drizzle's [`db push`](https://orm.drizzle.team/kit-docs/overview#prototyping-with-db-push) in development mode. By default, `push` is enabled for development mode only. |
| `migrationDir` | Customize the directory that migrations are stored. |
| `logger` | The instance of the logger to be passed to drizzle. By default Payload's will be used. |
| `idType` | A string of 'number', or 'uuid' that is used for the data type given to id columns. |
| `transactionOptions` | A SQLiteTransactionConfig object for transactions, or set to `false` to disable using transactions. [More details](https://orm.drizzle.team/docs/transactions) |
| `localesSuffix` | A string appended to the end of table names for storing localized fields. Default is '\_locales'. |
| `relationshipsSuffix` | A string appended to the end of table names for storing relationships. Default is '\_rels'. |
| `versionsSuffix` | A string appended to the end of table names for storing versions. Defaults to '\_v'. |
| `beforeSchemaInit` | Drizzle schema hook. Runs before the schema is built. [More Details](#beforeschemainit) |
| `afterSchemaInit` | Drizzle schema hook. Runs after the schema is built. [More Details](#afterschemainit) |
| `generateSchemaOutputFile` | Override generated schema from `payload generate:db-schema` file path. Defaults to `{CWD}/src/payload-generated.schema.ts` |
| `autoIncrement` | Pass `true` to enable SQLite [AUTOINCREMENT](https://www.sqlite.org/autoinc.html) for primary keys to ensure the same ID cannot be reused from deleted rows |
| `allowIDOnCreate` | Set to `true` to use the `id` passed in data on the create API operations without using a custom ID field. |
| `blocksAsJSON` | Store blocks as a JSON column instead of using the relational structure which can improve performance with a large amount of blocks |
| `busyTimeout` | Maximum time in milliseconds to wait when the database is locked. Default is `0`. |
| `wal` | Enable Write-Ahead Logging (WAL) mode for improved performance and concurrency. [More Details](#wal-mode) |
## Access to Drizzle
After Payload is initialized, this adapter will expose the full power of Drizzle to you for use if you need it.
To ensure type-safety, you need to generate Drizzle schema first with:
```sh
npx payload generate:db-schema
```
Then, you can access Drizzle as follows:
```ts
// Import table from the generated file
import { posts } from './payload-generated-schema'
// To avoid installing Drizzle, you can import everything that drizzle has from our re-export path.
import { eq, sql, and } from '@payloadcms/db-sqlite/drizzle'
// Drizzle's Querying API: https://orm.drizzle.team/docs/rqb
const posts = await payload.db.drizzle.query.posts.findMany()
// Drizzle's Select API https://orm.drizzle.team/docs/select
const result = await payload.db.drizzle
.select()
.from(posts)
.where(
and(eq(posts.id, 50), sql`lower(${posts.title}) = 'example post title'`),
)
```
## Tables and relations
In addition to exposing Drizzle directly, all of the tables and Drizzle relations are exposed for you via the `payload.db` property as well.
- Tables - `payload.db.tables`
- Relations - `payload.db.relations`
## Prototyping in development mode
Drizzle exposes two ways to work locally in development mode.
The first is [`db push`](https://orm.drizzle.team/kit-docs/overview#prototyping-with-db-push), which automatically pushes changes you make to your Payload Config (and therefore, Drizzle schema) to your database so you don't have to manually migrate every time you change your Payload Config. This only works in development mode, and should not be mixed with manually running [`migrate`](../database/migrations) commands.
You will be warned if any changes that you make will entail data loss while in development mode. Push is enabled by default, but you can opt out if you'd like.
Alternatively, you can disable `push` and rely solely on migrations to keep your local database in sync with your Payload Config.
## Migration workflows
In SQLite, migrations are a fundamental aspect of working with Payload and you should become familiar with how they work.
For more information about migrations, [click here](./migrations#when-to-run-migrations).
## Drizzle schema hooks
### beforeSchemaInit
Runs before the schema is built. You can use this hook to extend your database structure with tables that won't be managed by Payload.
```ts
import { sqliteAdapter } from '@payloadcms/db-sqlite'
import { integer, sqliteTable } from '@payloadcms/db-sqlite/drizzle/sqlite-core'
sqliteAdapter({
beforeSchemaInit: [
({ schema, adapter }) => {
return {
...schema,
tables: {
...schema.tables,
addedTable: sqliteTable('added_table', {
id: integer('id').primaryKey({ autoIncrement: true }),
}),
},
}
},
],
})
```
One use case is preserving your existing database structure when migrating to Payload. By default, Payload drops the current database schema, which may not be desirable in this scenario.
To quickly generate the Drizzle schema from your database you can use [Drizzle Introspection](https://orm.drizzle.team/kit-docs/commands#introspect--pull)
You should get the `schema.ts` file which may look like this:
```ts
import {
sqliteTable,
text,
uniqueIndex,
integer,
} from 'drizzle-orm/sqlite-core'
export const users = sqliteTable('users', {
id: integer('id').primaryKey({ autoIncrement: true }),
fullName: text('full_name'),
phone: text('phone', { length: 256 }),
})
export const countries = sqliteTable(
'countries',
{
id: integer('id').primaryKey({ autoIncrement: true }),
name: text('name', { length: 256 }),
},
(countries) => {
return {
nameIndex: uniqueIndex('name_idx').on(countries.name),
}
},
)
```
You can import them into your config and append to the schema with the `beforeSchemaInit` hook like this:
```ts
import { sqliteAdapter } from '@payloadcms/db-sqlite'
import { users, countries } from '../drizzle/schema'
sqliteAdapter({
beforeSchemaInit: [
({ schema, adapter }) => {
return {
...schema,
tables: {
...schema.tables,
users,
countries,
},
}
},
],
})
```
Make sure Payload doesn't overlap table names with its collections. For example, if you already have a collection with slug "users", you should either change the slug or `dbName` to change the table name for this collection.
### afterSchemaInit
Runs after the Drizzle schema is built. You can use this hook to modify the schema with features that aren't supported by Payload, or if you want to add a column that you don't want to be in the Payload config.
To extend a table, Payload exposes `extendTable` utility to the args. You can refer to the [Drizzle documentation](https://orm.drizzle.team/docs/sql-schema-declaration).
The following example adds the `extra_integer_column` column and a composite index on `country` and `city` columns.
```ts
import { sqliteAdapter } from '@payloadcms/db-sqlite'
import { index, integer } from '@payloadcms/db-sqlite/drizzle/sqlite-core'
import { buildConfig } from 'payload'
export default buildConfig({
collections: [
{
slug: 'places',
fields: [
{
name: 'country',
type: 'text',
},
{
name: 'city',
type: 'text',
},
],
},
],
db: sqliteAdapter({
afterSchemaInit: [
({ schema, extendTable, adapter }) => {
extendTable({
table: schema.tables.places,
columns: {
extraIntegerColumn: integer('extra_integer_column'),
},
extraConfig: (table) => ({
country_city_composite_index: index(
'country_city_composite_index',
).on(table.country, table.city),
}),
})
return schema
},
],
}),
})
```
### Note for generated schema:
Columns and tables, added in schema hooks won't be added to the generated via `payload generate:db-schema` Drizzle schema.
If you want them to be there, you either have to edit this file manually or mutate the internal Payload "raw" SQL schema in the `beforeSchemaInit`:
```ts
import { sqliteAdapter } from '@payloadcms/db-sqlite'
sqliteAdapter({
beforeSchemaInit: [
({ schema, adapter }) => {
// Add a new table
adapter.rawTables.myTable = {
name: 'my_table',
columns: {
my_id: {
name: 'my_id',
type: 'integer',
primaryKey: true,
},
},
}
// Add a new column to generated by Payload table:
adapter.rawTables.posts.columns.customColumn = {
name: 'custom_column',
// Note that Payload SQL doesn't support everything that Drizzle does.
type: 'integer',
notNull: true,
}
// Add a new index to generated by Payload table:
adapter.rawTables.posts.indexes.customColumnIdx = {
name: 'custom_column_idx',
unique: true,
on: ['custom_colu
gitextract_uabekduh/ ├── .github/ │ └── workflows/ │ └── on-payload-release.yml ├── .gitignore ├── .prettierignore ├── .prettierrc.json ├── .vscode/ │ ├── extensions.json │ └── settings.json ├── Caddyfile ├── LICENSE ├── README.md ├── algolia.d.ts ├── cssVariables.cjs ├── eslint.config.js ├── next-sitemap.config.cjs ├── next.config.js ├── package.json ├── public/ │ ├── js/ │ │ └── theme.js │ ├── llms-full.txt │ ├── llms.txt │ ├── robots.txt │ ├── sitemap-0.xml │ └── sitemap.xml ├── redirects.js ├── src/ │ ├── access/ │ │ ├── isAdmin.ts │ │ ├── isAdminOrSelf.ts │ │ └── publishedOnly.ts │ ├── access.ts │ ├── adapters/ │ │ ├── AlgoliaPagination/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ └── AlgoliaSearchBox/ │ │ ├── index.module.scss │ │ └── index.tsx │ ├── app/ │ │ ├── (frontend)/ │ │ │ ├── (cloud)/ │ │ │ │ ├── cloud/ │ │ │ │ │ ├── (tabs)/ │ │ │ │ │ │ ├── layout.tsx │ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ │ ├── page.tsx │ │ │ │ │ │ ├── page_client.tsx │ │ │ │ │ │ ├── settings/ │ │ │ │ │ │ │ ├── DeletionConfirmationForm/ │ │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ │ └── page.module.scss │ │ │ │ │ │ │ ├── layout.module.scss │ │ │ │ │ │ │ ├── layout.tsx │ │ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ │ │ ├── page.tsx │ │ │ │ │ │ │ └── page_client.tsx │ │ │ │ │ │ └── teams/ │ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── [team-slug]/ │ │ │ │ │ │ ├── (tabs)/ │ │ │ │ │ │ │ ├── layout.tsx │ │ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ │ │ ├── page.tsx │ │ │ │ │ │ │ ├── page_client.tsx │ │ │ │ │ │ │ └── settings/ │ │ │ │ │ │ │ ├── (tabs)/ │ │ │ │ │ │ │ │ ├── billing/ │ │ │ │ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ │ │ │ │ ├── page.tsx │ │ │ │ │ │ │ │ │ └── useCustomerPortal.tsx │ │ │ │ │ │ │ │ ├── invoices/ │ │ │ │ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ │ │ │ │ ├── page.tsx │ │ │ │ │ │ │ │ │ ├── page_client.tsx │ │ │ │ │ │ │ │ │ └── useInvoices.ts │ │ │ │ │ │ │ │ ├── members/ │ │ │ │ │ │ │ │ │ ├── UpdateRolesConfirmationForm/ │ │ │ │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ │ │ │ └── page.module.scss │ │ │ │ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ │ │ │ │ ├── page.tsx │ │ │ │ │ │ │ │ │ └── page_client.tsx │ │ │ │ │ │ │ │ └── subscriptions/ │ │ │ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ │ │ │ ├── page.tsx │ │ │ │ │ │ │ │ ├── page_client.tsx │ │ │ │ │ │ │ │ ├── reducer.ts │ │ │ │ │ │ │ │ └── useSubscriptions.ts │ │ │ │ │ │ │ ├── TeamBillingMessages/ │ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── layout.module.scss │ │ │ │ │ │ │ ├── layout.tsx │ │ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ │ │ ├── page.tsx │ │ │ │ │ │ │ └── page_client.tsx │ │ │ │ │ │ └── [project-slug]/ │ │ │ │ │ │ ├── (tabs)/ │ │ │ │ │ │ │ ├── (overview)/ │ │ │ │ │ │ │ │ ├── DeploymentLogs/ │ │ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ │ ├── InfraOffline/ │ │ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ │ ├── InfraOnline/ │ │ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ │ ├── ProjectBillingMessages/ │ │ │ │ │ │ │ │ ├── BadSubscription.tsx │ │ │ │ │ │ │ │ ├── MissingPaymentMethod.tsx │ │ │ │ │ │ │ │ ├── TrialMessage.tsx │ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── database/ │ │ │ │ │ │ │ │ ├── page.tsx │ │ │ │ │ │ │ │ └── page_client.tsx │ │ │ │ │ │ │ ├── file-storage/ │ │ │ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ │ │ │ ├── page.tsx │ │ │ │ │ │ │ │ └── page_client.tsx │ │ │ │ │ │ │ ├── layout.tsx │ │ │ │ │ │ │ ├── logs/ │ │ │ │ │ │ │ │ ├── page.tsx │ │ │ │ │ │ │ │ └── page_client.tsx │ │ │ │ │ │ │ └── settings/ │ │ │ │ │ │ │ ├── (build-settings)/ │ │ │ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ │ │ │ ├── page.tsx │ │ │ │ │ │ │ │ └── page_client.tsx │ │ │ │ │ │ │ ├── _layoutComponents/ │ │ │ │ │ │ │ │ ├── NoData/ │ │ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ │ └── SectionHeader/ │ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── billing/ │ │ │ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ │ ├── domains/ │ │ │ │ │ │ │ │ ├── AddDomain/ │ │ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ │ ├── ManageDomain/ │ │ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ │ ├── page.tsx │ │ │ │ │ │ │ │ └── page_client.tsx │ │ │ │ │ │ │ ├── email/ │ │ │ │ │ │ │ │ ├── AddEmailDomain/ │ │ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ │ ├── ManageEmailDomain/ │ │ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ │ ├── page.tsx │ │ │ │ │ │ │ │ └── page_client.tsx │ │ │ │ │ │ │ ├── environment-variables/ │ │ │ │ │ │ │ │ ├── AddEnvs/ │ │ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ │ ├── ManageEnvs/ │ │ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ │ ├── Secret/ │ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ │ │ │ ├── page.tsx │ │ │ │ │ │ │ │ └── validations.ts │ │ │ │ │ │ │ ├── layout.module.scss │ │ │ │ │ │ │ ├── layout.tsx │ │ │ │ │ │ │ ├── ownership/ │ │ │ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ │ │ │ ├── page.tsx │ │ │ │ │ │ │ │ └── page_client.tsx │ │ │ │ │ │ │ └── plan/ │ │ │ │ │ │ │ ├── DeletePlanButton/ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── DeletePlanModal/ │ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── configure/ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ └── env/ │ │ │ │ │ │ └── [environment-slug]/ │ │ │ │ │ │ └── (tabs)/ │ │ │ │ │ │ ├── (overview)/ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── ProjectBillingMessages/ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── database/ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── file-storage/ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── layout.tsx │ │ │ │ │ │ ├── logs/ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ └── settings/ │ │ │ │ │ │ ├── (build-settings)/ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── billing/ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── domains/ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── email/ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── environment-variables/ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── layout.tsx │ │ │ │ │ │ ├── ownership/ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ └── plan/ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── _actions/ │ │ │ │ │ │ └── revalidateCache.ts │ │ │ │ │ ├── _api/ │ │ │ │ │ │ ├── fetchGitHubToken.ts │ │ │ │ │ │ ├── fetchInstalls.ts │ │ │ │ │ │ ├── fetchInvoices.ts │ │ │ │ │ │ ├── fetchMe.ts │ │ │ │ │ │ ├── fetchPaymentMethod.ts │ │ │ │ │ │ ├── fetchPaymentMethods.ts │ │ │ │ │ │ ├── fetchPlans.ts │ │ │ │ │ │ ├── fetchProject.ts │ │ │ │ │ │ ├── fetchProjects.ts │ │ │ │ │ │ ├── fetchRepos.ts │ │ │ │ │ │ ├── fetchSubscriptions.ts │ │ │ │ │ │ ├── fetchTeam.ts │ │ │ │ │ │ ├── fetchTemplate.ts │ │ │ │ │ │ ├── fetchTemplates.ts │ │ │ │ │ │ ├── token.ts │ │ │ │ │ │ ├── updateCustomer.ts │ │ │ │ │ │ ├── updatePaymentMethod.ts │ │ │ │ │ │ └── updateSubscription.ts │ │ │ │ │ ├── _components/ │ │ │ │ │ │ ├── BranchSelector/ │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ └── reducer.ts │ │ │ │ │ │ ├── CloneOrDeployProgress/ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── CloudFooter/ │ │ │ │ │ │ │ ├── classes.module.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── CloudHeader/ │ │ │ │ │ │ │ ├── classes.module.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── CloudLogo/ │ │ │ │ │ │ │ ├── classes.module.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── ComparePlans/ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── CreditCardElement/ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── CreditCardList/ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ ├── reducer.ts │ │ │ │ │ │ │ └── usePaymentMethods.ts │ │ │ │ │ │ ├── CreditCardSelector/ │ │ │ │ │ │ │ ├── ProjectPaymentMethodSelector.tsx │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ └── useSubscription.ts │ │ │ │ │ │ ├── DashboardBreadcrumbs/ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── DashboardTabs/ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── InstallationButton/ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── InstallationSelector/ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ ├── MenuList/ │ │ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ │ ├── Option/ │ │ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ │ └── SingleValue/ │ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ ├── types.ts │ │ │ │ │ │ │ └── useGetInstalls.ts │ │ │ │ │ │ ├── InviteTeammates/ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── PlanSelector/ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── ProjectCard/ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── ProjectHeader/ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── RadioGroup/ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── RepoExists/ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── Sidebar/ │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ └── layout.module.scss │ │ │ │ │ │ ├── Tabs/ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── TeamDrawer/ │ │ │ │ │ │ │ ├── DrawerContent.module.scss │ │ │ │ │ │ │ ├── DrawerContent.tsx │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ └── types.ts │ │ │ │ │ │ ├── TeamInvitations/ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── TeamMembers/ │ │ │ │ │ │ │ ├── TeamMemberRow.module.scss │ │ │ │ │ │ │ ├── TeamMemberRow.tsx │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── TeamSelector/ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── UniqueDomain/ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ └── reducer.ts │ │ │ │ │ │ ├── UniqueRepoName/ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ └── UniqueSlug/ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ └── reducer.ts │ │ │ │ │ ├── _utilities/ │ │ │ │ │ │ ├── hasBadSubscription.ts │ │ │ │ │ │ ├── projectHasPaymentMethod.ts │ │ │ │ │ │ └── teamHasDefaultPaymentMethod.ts │ │ │ │ │ ├── layout.tsx │ │ │ │ │ ├── not-found.tsx │ │ │ │ │ └── slug.ts │ │ │ │ ├── cloud-terms/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── forgot-password/ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ ├── page.tsx │ │ │ │ │ └── page_client.tsx │ │ │ │ ├── join-team/ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ ├── page.tsx │ │ │ │ │ └── page_client.tsx │ │ │ │ ├── layout.module.scss │ │ │ │ ├── layout.tsx │ │ │ │ ├── login/ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ ├── page.tsx │ │ │ │ │ └── page_client.tsx │ │ │ │ ├── logout/ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ ├── page.tsx │ │ │ │ │ └── page_client.tsx │ │ │ │ ├── new/ │ │ │ │ │ ├── (checkout)/ │ │ │ │ │ │ ├── Checkout.module.scss │ │ │ │ │ │ ├── Checkout.tsx │ │ │ │ │ │ ├── EnvVars.module.scss │ │ │ │ │ │ ├── EnvVars.tsx │ │ │ │ │ │ ├── confirmCardPayment.ts │ │ │ │ │ │ ├── confirmCardSetup.ts │ │ │ │ │ │ ├── createSetupIntent.ts │ │ │ │ │ │ ├── createSubscription.ts │ │ │ │ │ │ ├── deploy.tsx │ │ │ │ │ │ └── reducer.ts │ │ │ │ │ ├── authorize/ │ │ │ │ │ │ ├── checkGitHubToken.ts │ │ │ │ │ │ ├── exchangeCode.ts │ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ │ ├── page.tsx │ │ │ │ │ │ └── page_client.tsx │ │ │ │ │ ├── clone/ │ │ │ │ │ │ ├── [template-slug]/ │ │ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ │ │ ├── page.tsx │ │ │ │ │ │ │ └── page_client.tsx │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── createDraftProject.tsx │ │ │ │ │ ├── import/ │ │ │ │ │ │ ├── RepoCard/ │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ │ ├── page.tsx │ │ │ │ │ │ ├── page_client.tsx │ │ │ │ │ │ └── useGetRepos.ts │ │ │ │ │ ├── layout.tsx │ │ │ │ │ └── page.tsx │ │ │ │ ├── reset-password/ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ ├── page.tsx │ │ │ │ │ └── page_client.tsx │ │ │ │ └── verify/ │ │ │ │ └── page.tsx │ │ │ ├── (pages)/ │ │ │ │ ├── [...slug]/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── case-studies/ │ │ │ │ │ └── [slug]/ │ │ │ │ │ ├── client_page.tsx │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── page.tsx │ │ │ │ ├── community-help/ │ │ │ │ │ ├── (posts)/ │ │ │ │ │ │ ├── discord/ │ │ │ │ │ │ │ └── [slug]/ │ │ │ │ │ │ │ ├── client_page.tsx │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── github/ │ │ │ │ │ │ │ └── [slug]/ │ │ │ │ │ │ │ ├── client_page.tsx │ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ └── layout.tsx │ │ │ │ │ ├── AlgoliaProvider/ │ │ │ │ │ │ ├── getInitialState.ts │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── ArchiveSearchBar/ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── client_page.tsx │ │ │ │ │ ├── index.module.scss │ │ │ │ │ ├── layout.tsx │ │ │ │ │ └── page.tsx │ │ │ │ ├── cookie/ │ │ │ │ │ ├── client_page.tsx │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── page.tsx │ │ │ │ ├── docs/ │ │ │ │ │ ├── [topic]/ │ │ │ │ │ │ └── [doc]/ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── dynamic/ │ │ │ │ │ │ └── [topic]/ │ │ │ │ │ │ └── [doc]/ │ │ │ │ │ │ ├── layout.tsx │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── fetchTopicsForSidebar.ts │ │ │ │ │ ├── local/ │ │ │ │ │ │ └── [topic]/ │ │ │ │ │ │ └── [doc]/ │ │ │ │ │ │ ├── layout.tsx │ │ │ │ │ │ └── page.tsx │ │ │ │ │ └── v2/ │ │ │ │ │ └── [topic]/ │ │ │ │ │ └── [doc]/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── layout.tsx │ │ │ │ ├── page.tsx │ │ │ │ ├── partners/ │ │ │ │ │ ├── [slug]/ │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── page.tsx │ │ │ │ ├── posts/ │ │ │ │ │ └── [category]/ │ │ │ │ │ ├── [slug]/ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── page.tsx │ │ │ │ ├── privacy/ │ │ │ │ │ ├── page.module.scss │ │ │ │ │ ├── page.tsx │ │ │ │ │ └── page_client.tsx │ │ │ │ ├── styleguide/ │ │ │ │ │ ├── PageContent/ │ │ │ │ │ │ ├── Breadcrumbs/ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── RenderDarkMode/ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── blocks/ │ │ │ │ │ │ ├── banner-block/ │ │ │ │ │ │ │ ├── client_page.tsx │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── call-to-action/ │ │ │ │ │ │ │ ├── client_page.tsx │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── card-grid/ │ │ │ │ │ │ │ ├── client_page.tsx │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── content-grid/ │ │ │ │ │ │ │ ├── client_page.tsx │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── form-block/ │ │ │ │ │ │ │ ├── client_page.tsx │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── hover-highlights/ │ │ │ │ │ │ │ ├── client_page.tsx │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── layout.tsx │ │ │ │ │ │ ├── link-grid/ │ │ │ │ │ │ │ ├── client_page.tsx │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ └── media-content/ │ │ │ │ │ │ ├── client_page.tsx │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── buttons/ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── cards/ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── fields/ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── forms/ │ │ │ │ │ │ ├── client_page.tsx │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── heros/ │ │ │ │ │ │ └── form-hero/ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── highlight/ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── icons/ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── layout.module.scss │ │ │ │ │ ├── layout.tsx │ │ │ │ │ ├── page.tsx │ │ │ │ │ └── typography/ │ │ │ │ │ └── page.tsx │ │ │ │ └── thanks-for-subscribing/ │ │ │ │ ├── client_page.tsx │ │ │ │ └── page.tsx │ │ │ ├── api/ │ │ │ │ ├── exit-preview/ │ │ │ │ │ └── route.ts │ │ │ │ ├── locate/ │ │ │ │ │ └── route.ts │ │ │ │ ├── og/ │ │ │ │ │ └── route.tsx │ │ │ │ ├── preview/ │ │ │ │ │ └── route.ts │ │ │ │ ├── revalidate/ │ │ │ │ │ └── route.ts │ │ │ │ ├── star-count/ │ │ │ │ │ └── route.ts │ │ │ │ ├── sync-algolia/ │ │ │ │ │ └── route.ts │ │ │ │ └── sync-ch/ │ │ │ │ └── route.ts │ │ │ ├── error.tsx │ │ │ ├── fonts.ts │ │ │ ├── gh/ │ │ │ │ └── page.tsx │ │ │ ├── layout.tsx │ │ │ ├── not-found.tsx │ │ │ └── types.ts │ │ ├── (payload)/ │ │ │ ├── admin/ │ │ │ │ ├── [[...segments]]/ │ │ │ │ │ ├── not-found.tsx │ │ │ │ │ └── page.tsx │ │ │ │ └── importMap.js │ │ │ ├── api/ │ │ │ │ ├── [...slug]/ │ │ │ │ │ └── route.ts │ │ │ │ ├── graphql/ │ │ │ │ │ └── route.ts │ │ │ │ └── graphql-playground/ │ │ │ │ └── route.ts │ │ │ ├── custom.scss │ │ │ └── layout.tsx │ │ ├── _data/ │ │ │ ├── index.ts │ │ │ ├── me.ts │ │ │ ├── plans.ts │ │ │ ├── project.ts │ │ │ ├── team.ts │ │ │ ├── templates.ts │ │ │ └── token.ts │ │ ├── api/ │ │ │ └── analytics/ │ │ │ ├── active-users/ │ │ │ │ ├── route.d.ts │ │ │ │ └── route.js │ │ │ ├── channel-groups/ │ │ │ │ ├── route.d.ts │ │ │ │ └── route.js │ │ │ ├── mockData.d.ts │ │ │ ├── mockData.js │ │ │ └── pageviews/ │ │ │ ├── route.d.ts │ │ │ └── route.js │ │ └── global-error.tsx │ ├── blocks/ │ │ ├── Banner/ │ │ │ └── index.ts │ │ ├── BlogContent/ │ │ │ └── index.ts │ │ ├── BlogMarkdown/ │ │ │ ├── Field/ │ │ │ │ ├── index.scss │ │ │ │ ├── index.tsx │ │ │ │ └── validate.ts │ │ │ └── index.ts │ │ ├── CallToAction/ │ │ │ └── index.ts │ │ ├── Callout/ │ │ │ └── index.ts │ │ ├── CardGrid/ │ │ │ └── index.ts │ │ ├── CaseStudiesHighlight/ │ │ │ └── index.ts │ │ ├── CaseStudyCards/ │ │ │ └── index.ts │ │ ├── CaseStudyParallax/ │ │ │ └── index.ts │ │ ├── Code/ │ │ │ └── index.ts │ │ ├── CodeFeature/ │ │ │ └── index.ts │ │ ├── ComparisonTable/ │ │ │ └── index.ts │ │ ├── Content/ │ │ │ └── index.ts │ │ ├── ContentGrid/ │ │ │ └── index.ts │ │ ├── Download/ │ │ │ └── index.ts │ │ ├── ExampleTabs/ │ │ │ └── index.ts │ │ ├── Form/ │ │ │ └── index.ts │ │ ├── HoverCards/ │ │ │ └── index.ts │ │ ├── HoverHighlights/ │ │ │ └── index.ts │ │ ├── LinkGrid/ │ │ │ └── index.ts │ │ ├── LogoGrid/ │ │ │ └── index.ts │ │ ├── Media/ │ │ │ └── index.ts │ │ ├── MediaContent/ │ │ │ └── index.ts │ │ ├── MediaContentAccordion/ │ │ │ └── index.ts │ │ ├── Pricing/ │ │ │ └── index.ts │ │ ├── ReusableContent/ │ │ │ └── index.ts │ │ ├── Slider/ │ │ │ └── index.ts │ │ ├── Statement/ │ │ │ └── index.ts │ │ ├── Steps/ │ │ │ └── index.ts │ │ └── StickyHighlights/ │ │ └── index.ts │ ├── collections/ │ │ ├── CaseStudies.ts │ │ ├── Categories.ts │ │ ├── CommunityHelp/ │ │ │ ├── extract-description.ts │ │ │ ├── index.ts │ │ │ └── updateAlgolia.ts │ │ ├── Docs/ │ │ │ ├── BranchButton/ │ │ │ │ ├── fetchAllBranches.ts │ │ │ │ ├── index.client.tsx │ │ │ │ ├── index.scss │ │ │ │ └── index.tsx │ │ │ ├── SaveButton/ │ │ │ │ ├── index.scss │ │ │ │ └── index.tsx │ │ │ ├── blocks/ │ │ │ │ ├── VideoDrawer/ │ │ │ │ │ └── index.ts │ │ │ │ ├── arrow/ │ │ │ │ │ └── index.ts │ │ │ │ ├── banner/ │ │ │ │ │ └── index.ts │ │ │ │ ├── bulletList/ │ │ │ │ │ └── index.ts │ │ │ │ ├── code/ │ │ │ │ │ ├── CodeFields.tsx │ │ │ │ │ ├── converter.ts │ │ │ │ │ ├── converterClient.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── lightDarkImage/ │ │ │ │ │ └── index.ts │ │ │ │ ├── payloadMedia/ │ │ │ │ │ └── index.tsx │ │ │ │ ├── pill/ │ │ │ │ │ └── index.ts │ │ │ │ ├── resource/ │ │ │ │ │ └── index.ts │ │ │ │ ├── restExamples/ │ │ │ │ │ └── index.ts │ │ │ │ ├── shared.ts │ │ │ │ ├── tableWithDrawers/ │ │ │ │ │ └── index.ts │ │ │ │ ├── upload/ │ │ │ │ │ └── index.ts │ │ │ │ └── youtube/ │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── mdxToLexical.ts │ │ │ ├── topicOrder.ts │ │ │ └── types.ts │ │ ├── Media.ts │ │ ├── Pages.ts │ │ ├── PartnerFilters.ts │ │ ├── Partners.ts │ │ ├── Posts.ts │ │ ├── ReusableContent.ts │ │ └── Users.ts │ ├── components/ │ │ ├── Accordion/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── AfterNavActions/ │ │ │ ├── index.scss │ │ │ └── index.tsx │ │ ├── Analytics/ │ │ │ ├── GoogleAnalytics/ │ │ │ │ └── index.tsx │ │ │ └── GoogleTagManager/ │ │ │ └── index.tsx │ │ ├── Archive/ │ │ │ ├── MobileNav/ │ │ │ │ └── index.tsx │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── AuthorTag/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Avatar/ │ │ │ ├── DropdownMenu/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── BackButton/ │ │ │ └── index.tsx │ │ ├── BackgroundGradient/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── BackgroundGrid/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── BackgroundScanline/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Banner/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── BigThree/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── BlockSpacing/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── BlockWrapper/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── BorderBox/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Breadcrumbs/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Button/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── CMSForm/ │ │ │ ├── Label/ │ │ │ │ ├── index.module.scss │ │ │ │ ├── index.tsx │ │ │ │ └── types.ts │ │ │ ├── Submit/ │ │ │ │ └── index.tsx │ │ │ ├── Width/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── fields/ │ │ │ │ ├── Checkbox/ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── index.tsx │ │ │ │ ├── Select/ │ │ │ │ │ ├── countries.ts │ │ │ │ │ ├── index.module.scss │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── states.ts │ │ │ │ ├── Text/ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── index.tsx │ │ │ │ ├── Textarea/ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── index.tsx │ │ │ │ └── shared.scss │ │ │ ├── fields.module.scss │ │ │ ├── fields.tsx │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── CMSLink/ │ │ │ └── index.tsx │ │ ├── ChangeHeaderTheme/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── CircleIconButton/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Code/ │ │ │ ├── index.module.scss │ │ │ ├── index.tsx │ │ │ ├── theme.ts │ │ │ └── types.ts │ │ ├── CodeBlip/ │ │ │ ├── Button/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── CodeBlipContext.tsx │ │ │ ├── Modal/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ └── index.tsx │ │ ├── CommandLine/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── ContributionTable/ │ │ │ ├── api.ts │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── CopyToClipboard/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── CreatePayloadApp/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── DiscordGitBody/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── DiscordGitCTA/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── DiscordGitComments/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── DiscordGitIntro/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── DiscordUsersPill/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── DocsNavigation/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Drawer/ │ │ │ ├── index.module.scss │ │ │ ├── index.tsx │ │ │ ├── types.ts │ │ │ └── useDrawerSlug.tsx │ │ ├── DropdownMenu/ │ │ │ ├── MenuContent/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── EdgeScroll/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── ErrorMessage/ │ │ │ └── index.tsx │ │ ├── ExtendedBackground/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── FeaturedBlogPost/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Feedback/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── FileAttachment/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Footer/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── GithubStarsPill/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── GuestSocials/ │ │ │ └── index.tsx │ │ ├── Gutter/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── HR/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Header/ │ │ │ ├── DesktopNav/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Docsearch/ │ │ │ │ ├── Component.tsx │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── MobileNav/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Heading/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Hero/ │ │ │ ├── BreadcrumbsBar/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── CenteredContent/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── ContentMedia/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Default/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── FormHero/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Gradient/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Home/ │ │ │ │ ├── LogoShowcase/ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── index.tsx │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── HomeNew/ │ │ │ │ ├── LogoShowcase/ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── index.tsx │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Livestream/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Three/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── index.tsx │ │ │ └── useGetHeroPadding.ts │ │ ├── Highlight/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Indicator/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Label/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── LargeBody/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── LargeRadio/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── LineDraw/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── LoadingShimmer/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── MDX/ │ │ │ └── components/ │ │ │ ├── Table/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ └── TableWithDrawers/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── MaxWidth/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Media/ │ │ │ ├── Image/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Video/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── index.tsx │ │ │ └── types.ts │ │ ├── MediaParallax/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── MediaStack/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Message/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── ModalWindow/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── NewProject/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── NewsletterSignUp/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── OpenPost/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Pagination/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── PartnerDirectory/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── PartnerGrid/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Payload3D/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── PayloadRedirects/ │ │ │ └── index.tsx │ │ ├── Pill/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── PixelBackground/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Post/ │ │ │ ├── AuthorsList/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── PrivacyBanner/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── RedeployButton/ │ │ │ ├── index.scss │ │ │ └── index.tsx │ │ ├── RefreshMdxToLexicalButton/ │ │ │ ├── index.scss │ │ │ └── index.tsx │ │ ├── RefreshRouterOnSave/ │ │ │ └── index.tsx │ │ ├── RelatedHelpList/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── RelatedResources/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── RenderBlocks/ │ │ │ ├── index.tsx │ │ │ └── utilities.ts │ │ ├── RenderDocs/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── RenderParams/ │ │ │ ├── Component.tsx │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── RichText/ │ │ │ ├── Arrow/ │ │ │ │ ├── index.scss │ │ │ │ └── index.tsx │ │ │ ├── BulletList/ │ │ │ │ ├── index.scss │ │ │ │ └── index.tsx │ │ │ ├── CustomTable/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Heading/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── LightDarkImage/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── PayloadMedia/ │ │ │ │ └── index.tsx │ │ │ ├── Pill/ │ │ │ │ ├── index.scss │ │ │ │ └── index.tsx │ │ │ ├── ResourceBlock/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── RestExamples/ │ │ │ │ ├── generateRequest.tsx │ │ │ │ ├── generateResponse.tsx │ │ │ │ ├── index.module.scss │ │ │ │ ├── index.tsx │ │ │ │ └── types.ts │ │ │ ├── Table/ │ │ │ │ └── index.tsx │ │ │ ├── TableWithDrawers/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Upload/ │ │ │ │ └── index.tsx │ │ │ ├── UploadBlock/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Video/ │ │ │ │ ├── Vimeo/ │ │ │ │ │ └── index.tsx │ │ │ │ ├── YouTube/ │ │ │ │ │ └── index.tsx │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── VideoDrawer/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── context.tsx │ │ │ ├── formatAnchor.ts │ │ │ ├── index.scss │ │ │ └── index.tsx │ │ ├── SimpleLogs/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── SocialIcon/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Spinner/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── SplitAnimate/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── SpotlightAnimation/ │ │ │ ├── index.module.scss │ │ │ ├── index.tsx │ │ │ └── types.ts │ │ ├── SyncCommunityHelp/ │ │ │ ├── index.scss │ │ │ └── index.tsx │ │ ├── SyncDocsButton/ │ │ │ ├── index.scss │ │ │ └── index.tsx │ │ ├── SyncToAlgolia/ │ │ │ ├── index.scss │ │ │ └── index.tsx │ │ ├── TableCheckboxField/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── TableOfContents/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── TemplateCardsBlock/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Tooltip/ │ │ │ ├── TooltipContent/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── TopBar/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── UniversalTruth/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── VersionSelector/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── YouTube/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── blocks/ │ │ │ ├── Banner/ │ │ │ │ └── index.tsx │ │ │ ├── BlogContent/ │ │ │ │ └── index.tsx │ │ │ ├── BlogMarkdown/ │ │ │ │ ├── Block.tsx │ │ │ │ └── index.tsx │ │ │ ├── CallToAction/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Callout/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── CardGrid/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── CaseStudiesHighlight/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── CaseStudyCards/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── CaseStudyParallax/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── CodeBlock/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── CodeFeature/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── ComparisonTable/ │ │ │ │ ├── Icons/ │ │ │ │ │ └── index.tsx │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Content/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── ContentGrid/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Download/ │ │ │ │ ├── Buttons/ │ │ │ │ │ └── index.tsx │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── FormBlock/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── HoverCards/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── HoverHighlights/ │ │ │ │ ├── Highlights/ │ │ │ │ │ └── index.tsx │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── LinkGrid/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── LogoGrid/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── MediaBlock/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── MediaContent/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── MediaContentAccordion/ │ │ │ │ ├── Desktop/ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── index.tsx │ │ │ │ ├── Mobile/ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── index.tsx │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Pricing/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── RelatedPosts/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── ReusableContent/ │ │ │ │ └── index.tsx │ │ │ ├── Slider/ │ │ │ │ ├── QuoteCard/ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── index.tsx │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Statement/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Steps/ │ │ │ │ ├── Step/ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── index.tsx │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ └── StickyHighlights/ │ │ │ ├── Highlight/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ └── cards/ │ │ ├── ContentMediaCard/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── DefaultCard/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── PartnerCard/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── PricingCard/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── SquareCard/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ └── types.ts │ ├── constants.ts │ ├── css/ │ │ ├── app.scss │ │ ├── colors.scss │ │ ├── common.scss │ │ ├── docsearch.scss │ │ ├── github.scss │ │ ├── grid.scss │ │ ├── queries.scss │ │ ├── theme.scss │ │ ├── toasts.scss │ │ ├── type.scss │ │ └── vars.scss │ ├── fields/ │ │ ├── addToDocs/ │ │ │ ├── Label.tsx │ │ │ ├── index.module.scss │ │ │ └── index.ts │ │ ├── blockFields.ts │ │ ├── codeBlips.ts │ │ ├── fullTitle/ │ │ │ ├── index.ts │ │ │ └── populateFullTitle.ts │ │ ├── hero.ts │ │ ├── link.ts │ │ ├── linkGroup.ts │ │ ├── livestreamFields.ts │ │ ├── richText/ │ │ │ ├── features/ │ │ │ │ ├── label/ │ │ │ │ │ ├── LabelNode.ts │ │ │ │ │ ├── client/ │ │ │ │ │ │ ├── icon/ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ └── styles.scss │ │ │ │ │ └── server/ │ │ │ │ │ └── index.ts │ │ │ │ └── largeBody/ │ │ │ │ ├── LargeBodyNode.ts │ │ │ │ ├── client/ │ │ │ │ │ ├── icon/ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── styles.scss │ │ │ │ └── server/ │ │ │ │ └── index.ts │ │ │ └── index.ts │ │ └── slug.ts │ ├── forms/ │ │ ├── Error/ │ │ │ ├── index.module.scss │ │ │ ├── index.tsx │ │ │ └── types.ts │ │ ├── Form/ │ │ │ ├── context.ts │ │ │ ├── index.tsx │ │ │ ├── initialContext.ts │ │ │ ├── reduceFieldsToValues.ts │ │ │ └── reducer.ts │ │ ├── FormProcessing/ │ │ │ └── index.tsx │ │ ├── FormSubmissionError/ │ │ │ └── index.tsx │ │ ├── Label/ │ │ │ ├── index.module.scss │ │ │ ├── index.tsx │ │ │ └── types.ts │ │ ├── Submit/ │ │ │ └── index.tsx │ │ ├── fields/ │ │ │ ├── Array/ │ │ │ │ ├── context.tsx │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Checkbox/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Number/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── RadioGroup/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Secret/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Select/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Text/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Textarea/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── shared.scss │ │ │ ├── types.ts │ │ │ └── useField/ │ │ │ └── index.tsx │ │ ├── types.ts │ │ ├── useFormField/ │ │ │ ├── index.tsx │ │ │ └── types.ts │ │ └── validations.ts │ ├── globals/ │ │ ├── CustomRowLabelNavItems.tsx │ │ ├── CustomRowLabelTabs.tsx │ │ ├── Footer.ts │ │ ├── GetStarted.ts │ │ ├── MainMenu.ts │ │ ├── PartnerProgram.ts │ │ └── TopBar.ts │ ├── graphics/ │ │ ├── CalendarIcon/ │ │ │ └── index.tsx │ │ ├── ChevronIcon/ │ │ │ └── index.tsx │ │ ├── ClockIcon/ │ │ │ └── index.tsx │ │ ├── CommentsIcon/ │ │ │ └── index.tsx │ │ ├── CommitIcon/ │ │ │ └── index.tsx │ │ ├── DiscordIcon/ │ │ │ └── index.tsx │ │ ├── DownloadIcon/ │ │ │ └── index.tsx │ │ ├── FacebookIcon/ │ │ │ └── index.tsx │ │ ├── FilterIcon/ │ │ │ └── index.tsx │ │ ├── FullLogo/ │ │ │ └── index.tsx │ │ ├── GitHub/ │ │ │ └── index.tsx │ │ ├── GithubIcon/ │ │ │ └── index.tsx │ │ ├── InfoIcon/ │ │ │ └── index.tsx │ │ ├── InstagramIcon/ │ │ │ └── index.tsx │ │ ├── MenuIcon/ │ │ │ └── index.tsx │ │ ├── PayloadIcon/ │ │ │ └── index.tsx │ │ ├── SearchIcon/ │ │ │ └── index.tsx │ │ ├── SearchIconV2/ │ │ │ └── index.tsx │ │ ├── ThemeAutoIcon/ │ │ │ └── index.tsx │ │ ├── ThemeDarkIcon/ │ │ │ └── index.tsx │ │ ├── ThemeLightIcon/ │ │ │ └── index.tsx │ │ ├── TwitterIcon/ │ │ │ └── index.tsx │ │ ├── TwitterIconAlt/ │ │ │ └── index.tsx │ │ ├── TwitterIconV2/ │ │ │ └── index.tsx │ │ └── YoutubeIcon/ │ │ └── index.tsx │ ├── hooks/ │ │ ├── revalidateRedirects.ts │ │ └── usePopulateDocument.ts │ ├── icons/ │ │ ├── ArrowIcon/ │ │ │ └── index.tsx │ │ ├── ArrowRightIcon/ │ │ │ └── index.tsx │ │ ├── BranchIcon/ │ │ │ └── index.tsx │ │ ├── ChainLinkIcon/ │ │ │ └── index.tsx │ │ ├── CheckIcon/ │ │ │ └── index.tsx │ │ ├── ChevronDownIcon/ │ │ │ └── index.tsx │ │ ├── ChevronIcon/ │ │ │ └── index.tsx │ │ ├── ChevronUpDownIcon/ │ │ │ └── index.tsx │ │ ├── CloseIcon/ │ │ │ └── index.tsx │ │ ├── CodeIcon/ │ │ │ └── index.tsx │ │ ├── Copy/ │ │ │ └── index.tsx │ │ ├── CopyIcon/ │ │ │ └── index.tsx │ │ ├── CrosshairIcon/ │ │ │ └── index.tsx │ │ ├── ErrorIcon/ │ │ │ └── index.tsx │ │ ├── ExternalLinkIcon/ │ │ │ └── index.tsx │ │ ├── EyeIcon/ │ │ │ └── index.tsx │ │ ├── FolderIcon/ │ │ │ └── index.tsx │ │ ├── GradientBorderIcon/ │ │ │ └── index.tsx │ │ ├── InfoIcon/ │ │ │ └── index.tsx │ │ ├── LoaderIcon/ │ │ │ └── index.tsx │ │ ├── PlayIcon/ │ │ │ └── index.tsx │ │ ├── PlusIcon/ │ │ │ └── index.tsx │ │ ├── QuoteIcon/ │ │ │ └── index.tsx │ │ ├── QuoteIconAlt/ │ │ │ └── index.tsx │ │ ├── SearchIcon/ │ │ │ └── index.tsx │ │ ├── TrashIcon/ │ │ │ └── index.tsx │ │ ├── index.module.scss │ │ └── types.ts │ ├── migrate.ts │ ├── migrations/ │ │ ├── 20241116_194708_migration.ts │ │ └── index.ts │ ├── payload-cloud-types.ts │ ├── payload-types.ts │ ├── payload.config.ts │ ├── plugins/ │ │ └── opsCounter.ts │ ├── providers/ │ │ ├── Auth/ │ │ │ └── index.tsx │ │ ├── ComputedCSSValues/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── HeaderIntersectionObserver/ │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── PageTransition/ │ │ │ └── index.tsx │ │ ├── Privacy/ │ │ │ └── index.tsx │ │ ├── Theme/ │ │ │ ├── index.tsx │ │ │ ├── shared.ts │ │ │ └── types.ts │ │ ├── ToastContainer/ │ │ │ ├── icons/ │ │ │ │ ├── Error.tsx │ │ │ │ ├── Info.tsx │ │ │ │ ├── Success.tsx │ │ │ │ └── Warning.tsx │ │ │ └── index.tsx │ │ └── index.tsx │ ├── scripts/ │ │ ├── clearDuplicateThreads.ts │ │ ├── fetchDiscord.ts │ │ ├── fetchDocs.ts │ │ ├── fetchGitHub.ts │ │ ├── generateLLMs.ts │ │ ├── migrateAuthors.js │ │ ├── migrateVersions.ts │ │ ├── redeployWebsite.ts │ │ ├── syncDocs.ts │ │ └── syncToAlgolia.ts │ ├── seo/ │ │ └── mergeOpenGraph.ts │ ├── ts-helpers/ │ │ └── requireField.ts │ └── utilities/ │ ├── analytics.ts │ ├── can-use-dom.ts │ ├── check-team-roles.ts │ ├── decode-base-64.ts │ ├── deepMerge.ts │ ├── format-date-time.ts │ ├── formatPagePath.ts │ ├── formatPermalink.js │ ├── formatPreviewURL.ts │ ├── formatSlug.ts │ ├── generate-route-path.ts │ ├── get-cookie.ts │ ├── get-relative-date.ts │ ├── get-specific-date-time.ts │ ├── get-team-twitter.ts │ ├── get-video.ts │ ├── getDocument.ts │ ├── getRedirects.ts │ ├── getSafeRedirect.ts │ ├── is-expanded-doc.ts │ ├── isNumber.ts │ ├── isValidParamID.ts │ ├── merge-project-environment.ts │ ├── oxford-comma.ts │ ├── parseCookies.ts │ ├── price-from-json.ts │ ├── qs.ts │ ├── revalidate.ts │ ├── revalidatePage.ts │ ├── sanitizeSlug.ts │ ├── slug-to-text.ts │ ├── slugify.ts │ ├── to-kebab-case.ts │ ├── use-click-away.ts │ ├── use-cloud-api.ts │ ├── use-debounce.ts │ ├── use-is-mounted.tsx │ ├── use-pathname-segments.ts │ ├── use-popup-window.ts │ ├── use-resize.ts │ ├── use-star-count.ts │ ├── use-websocket.tsx │ ├── useIntersection.ts │ └── uuid.ts ├── tsconfig.json └── vercel.json
SYMBOL INDEX (682 symbols across 314 files)
FILE: next.config.js
method headers (line 135) | async headers() {
FILE: src/app/(frontend)/(cloud)/cloud-terms/page.tsx
function TermsClientPage (line 8) | function TermsClientPage() {
FILE: src/app/(frontend)/(cloud)/cloud/(tabs)/settings/layout.tsx
type ProjectSettingsLayoutType (line 13) | type ProjectSettingsLayoutType = {
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/page.tsx
function generateMetadata (line 26) | async function generateMetadata({
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/billing/page.tsx
function generateMetadata (line 76) | async function generateMetadata({
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/invoices/page.tsx
function generateMetadata (line 37) | async function generateMetadata({
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/members/UpdateRolesConfirmationForm/index.tsx
type UpdateRolesConfirmationFormProps (line 15) | interface UpdateRolesConfirmationFormProps {
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/members/page.tsx
function generateMetadata (line 19) | async function generateMetadata({
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/subscriptions/page.tsx
function generateMetadata (line 39) | async function generateMetadata({
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/page.tsx
function generateMetadata (line 20) | async function generateMetadata({
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/(overview)/DeploymentLogs/index.tsx
type Props (line 108) | type Props = {
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/(overview)/InfraOffline/index.tsx
type DeploymentPhases (line 20) | type DeploymentPhases = RequireField<Project, 'infraStatus'>['infraStatus']
type DeploymentStates (line 21) | type DeploymentStates = {
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/(overview)/InfraOnline/index.tsx
type FinalDeploymentStages (line 21) | type FinalDeploymentStages = Extract<Deployment['deploymentStatus'], 'AC...
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/layout.tsx
function generateMetadata (line 126) | async function generateMetadata({
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/(build-settings)/page.tsx
function generateMetadata (line 35) | async function generateMetadata({
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/_layoutComponents/NoData/index.tsx
type Props (line 5) | type Props = {
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/_layoutComponents/SectionHeader/index.tsx
type Props (line 7) | type Props = {
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/billing/page.tsx
function generateMetadata (line 129) | async function generateMetadata({
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/domains/ManageDomain/index.tsx
type Props (line 18) | type Props = {
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/domains/page.tsx
function generateMetadata (line 31) | async function generateMetadata({
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/email/ManageEmailDomain/index.tsx
type Props (line 23) | type Props = {
type VerificationStatus (line 30) | type VerificationStatus = 'not_started' | 'pending' | 'verified'
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/email/page.tsx
function generateMetadata (line 30) | async function generateMetadata({
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/environment-variables/AddEnvs/index.tsx
type AddEnvsProps (line 19) | type AddEnvsProps = {
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/environment-variables/ManageEnvs/index.tsx
type Props (line 26) | type Props = {
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/environment-variables/page.tsx
function generateMetadata (line 94) | async function generateMetadata({
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/ownership/page.tsx
function generateMetadata (line 26) | async function generateMetadata({
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/plan/DeletePlanModal/index.tsx
type DeletePlanModalProps (line 21) | type DeletePlanModalProps = {
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/plan/page.tsx
function generateMetadata (line 81) | async function generateMetadata({
FILE: src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/configure/page.tsx
function generateMetadata (line 63) | async function generateMetadata({
FILE: src/app/(frontend)/(cloud)/cloud/_actions/revalidateCache.ts
function revalidateCache (line 11) | async function revalidateCache(args: { path?: string; tag?: string }): P...
FILE: src/app/(frontend)/(cloud)/cloud/_api/fetchGitHubToken.ts
type GitHubResponse (line 3) | type GitHubResponse = Endpoints['GET /user']['response']
FILE: src/app/(frontend)/(cloud)/cloud/_api/fetchInstalls.ts
type GitHubInstallationsResponse (line 5) | type GitHubInstallationsResponse = Endpoints['GET /user/installations'][...
type Install (line 7) | type Install = GitHubInstallationsResponse['data']['installations'][0]
FILE: src/app/(frontend)/(cloud)/cloud/_api/fetchInvoices.ts
type Invoice (line 6) | interface Invoice {
type InvoicesResult (line 34) | interface InvoicesResult {
FILE: src/app/(frontend)/(cloud)/cloud/_api/fetchProject.ts
type ProjectWithSubscription (line 13) | type ProjectWithSubscription = {
type ProjectWithSubscriptionWithTeamAndCustomer (line 83) | type ProjectWithSubscriptionWithTeamAndCustomer = {
FILE: src/app/(frontend)/(cloud)/cloud/_api/fetchProjects.ts
type ProjectsRes (line 8) | interface ProjectsRes {
FILE: src/app/(frontend)/(cloud)/cloud/_api/fetchRepos.ts
type GitHubResponse (line 7) | type GitHubResponse =
type RepoResults (line 10) | type RepoResults = {} & GitHubResponse['data']
type Repo (line 12) | type Repo = GitHubResponse['data']['repositories'][0]
FILE: src/app/(frontend)/(cloud)/cloud/_api/fetchSubscriptions.ts
type Subscription (line 6) | interface Subscription {
type SubscriptionsResult (line 41) | interface SubscriptionsResult {
FILE: src/app/(frontend)/(cloud)/cloud/_api/fetchTeam.ts
type TeamWithCustomer (line 8) | type TeamWithCustomer = {
type Customer (line 14) | interface Customer {
FILE: src/app/(frontend)/(cloud)/cloud/_components/BranchSelector/index.tsx
type GitHubListBranchesResponse (line 12) | type GitHubListBranchesResponse = Endpoints['GET /repos/{owner}/{repo}/b...
type GitHubFullRepoResponse (line 13) | type GitHubFullRepoResponse = Endpoints['GET /repos/{owner}/{repo}']['re...
FILE: src/app/(frontend)/(cloud)/cloud/_components/BranchSelector/reducer.ts
type BranchState (line 1) | interface BranchState {
type BranchAction (line 6) | interface BranchAction {
FILE: src/app/(frontend)/(cloud)/cloud/_components/ComparePlans/index.tsx
type ComparePlansProps (line 13) | type ComparePlansProps = {
FILE: src/app/(frontend)/(cloud)/cloud/_components/CreditCardList/index.tsx
type CreditCardListType (line 25) | type CreditCardListType = {
FILE: src/app/(frontend)/(cloud)/cloud/_components/CreditCardList/reducer.ts
type ADD_CARD (line 3) | interface ADD_CARD {
type DELETE_CARD (line 8) | interface DELETE_CARD {
type RESET_CARDS (line 13) | interface RESET_CARDS {
type Action (line 18) | type Action = ADD_CARD | DELETE_CARD | RESET_CARDS
FILE: src/app/(frontend)/(cloud)/cloud/_components/CreditCardList/usePaymentMethods.ts
type SaveNewPaymentMethod (line 15) | type SaveNewPaymentMethod = (paymentMethodID: string) => Promise<null | ...
FILE: src/app/(frontend)/(cloud)/cloud/_components/CreditCardSelector/index.tsx
type CreditCardSelectorType (line 14) | type CreditCardSelectorType = {
FILE: src/app/(frontend)/(cloud)/cloud/_components/CreditCardSelector/useSubscription.ts
type Subscription (line 6) | interface Subscription {
FILE: src/app/(frontend)/(cloud)/cloud/_components/DashboardTabs/index.tsx
type TabsType (line 11) | type TabsType = {
FILE: src/app/(frontend)/(cloud)/cloud/_components/InstallationSelector/types.ts
type InstallationSelectorProps (line 3) | interface InstallationSelectorProps {
FILE: src/app/(frontend)/(cloud)/cloud/_components/InstallationSelector/useGetInstalls.ts
type GitHubOrgsResponse (line 7) | type GitHubOrgsResponse = Endpoints['GET /user/memberships/orgs']['respo...
type GitHubOrg (line 9) | type GitHubOrg = GitHubOrgsResponse['data'][0]
type Add (line 11) | interface Add {
type Set (line 16) | interface Set {
type Action (line 21) | type Action = Add | Set
type UseGetInstalls (line 34) | type UseGetInstalls = (args?: {
FILE: src/app/(frontend)/(cloud)/cloud/_components/PlanSelector/index.tsx
type PlanSelectorProps (line 8) | type PlanSelectorProps = {
FILE: src/app/(frontend)/(cloud)/cloud/_components/ProjectHeader/index.tsx
function ProjectHeader (line 11) | function ProjectHeader({ environmentOptions, title }) {
FILE: src/app/(frontend)/(cloud)/cloud/_components/RadioGroup/index.tsx
type RadioOption (line 6) | type RadioOption = {
FILE: src/app/(frontend)/(cloud)/cloud/_components/RepoExists/index.tsx
type GitHubResponse (line 13) | type GitHubResponse = Endpoints['GET /repos/{owner}/{repo}']['response']
FILE: src/app/(frontend)/(cloud)/cloud/_components/Tabs/index.tsx
type Tab (line 10) | type Tab = {
FILE: src/app/(frontend)/(cloud)/cloud/_components/TeamDrawer/types.ts
type TeamDrawerProps (line 5) | interface TeamDrawerProps {
type TeamDrawerTogglerProps (line 12) | type TeamDrawerTogglerProps = {
type UseTeamDrawer (line 19) | type UseTeamDrawer = (args?: { team?: Team }) => [
FILE: src/app/(frontend)/(cloud)/cloud/_components/TeamMembers/index.tsx
type Member (line 10) | type Member = {
FILE: src/app/(frontend)/(cloud)/cloud/_components/UniqueDomain/reducer.ts
type ValidatedDomainResult (line 1) | interface ValidatedDomainResult {
type ValidatedDomainAction (line 6) | type ValidatedDomainAction =
FILE: src/app/(frontend)/(cloud)/cloud/_components/UniqueRepoName/index.tsx
type GitHubResponse (line 13) | type GitHubResponse = Endpoints['GET /repos/{owner}/{repo}']['response']
FILE: src/app/(frontend)/(cloud)/cloud/_components/UniqueSlug/reducer.ts
type SlugValidationResult (line 1) | interface SlugValidationResult {
type SlugValidationAction (line 8) | type SlugValidationAction =
FILE: src/app/(frontend)/(cloud)/cloud/not-found.tsx
function NotFound (line 4) | function NotFound() {
FILE: src/app/(frontend)/(cloud)/join-team/page.tsx
function JoinTeamPage (line 11) | async function JoinTeamPage(props) {
FILE: src/app/(frontend)/(cloud)/new/(checkout)/createSetupIntent.ts
type PayloadStripeSetupIntent (line 3) | interface PayloadStripeSetupIntent {
FILE: src/app/(frontend)/(cloud)/new/(checkout)/createSubscription.ts
type PayloadStripeSubscription (line 4) | interface PayloadStripeSubscription {
FILE: src/app/(frontend)/(cloud)/new/(checkout)/reducer.ts
type SET_PLAN (line 6) | interface SET_PLAN {
type SET_TEAM (line 11) | interface SET_TEAM {
type UPDATE_STATE (line 16) | interface UPDATE_STATE {
type SET_PAYMENT_METHOD (line 21) | interface SET_PAYMENT_METHOD {
type SET_FREE_TRIAL (line 26) | interface SET_FREE_TRIAL {
type Action (line 31) | type Action = SET_FREE_TRIAL | SET_PAYMENT_METHOD | SET_PLAN | SET_TEAM ...
type CheckoutState (line 33) | interface CheckoutState {
FILE: src/app/(frontend)/(cloud)/new/authorize/checkGitHubToken.ts
type GitHubResponse (line 3) | type GitHubResponse = Endpoints['GET /user']['response']
FILE: src/app/(frontend)/(cloud)/new/clone/[template-slug]/page.tsx
function generateMetadata (line 63) | async function generateMetadata({
FILE: src/app/(frontend)/(cloud)/new/layout.tsx
function NewProjectLayout (line 7) | async function NewProjectLayout({ children }: { children: React.ReactNod...
FILE: src/app/(frontend)/(cloud)/new/page.tsx
function NewProjectPage (line 12) | async function NewProjectPage({
FILE: src/app/(frontend)/(pages)/[...slug]/page.tsx
function generateStaticParams (line 46) | async function generateStaticParams() {
function generateMetadata (line 55) | async function generateMetadata({
FILE: src/app/(frontend)/(pages)/case-studies/[slug]/page.tsx
function generateStaticParams (line 40) | async function generateStaticParams() {
function generateMetadata (line 49) | async function generateMetadata({
FILE: src/app/(frontend)/(pages)/community-help/(posts)/discord/[slug]/client_page.tsx
type Attachments (line 14) | type Attachments = {
type Messages (line 33) | type Messages = {
type ThreadProps (line 42) | type ThreadProps = {
FILE: src/app/(frontend)/(pages)/community-help/(posts)/discord/[slug]/page.tsx
function generateStaticParams (line 79) | async function generateStaticParams() {
function generateMetadata (line 94) | async function generateMetadata({
FILE: src/app/(frontend)/(pages)/community-help/(posts)/github/[slug]/client_page.tsx
type DateFromSource (line 13) | type DateFromSource = string
type Author (line 14) | type Author = {
type Comment (line 19) | type Comment = {
type Answer (line 26) | type Answer = {
type DiscussionProps (line 35) | type DiscussionProps = {
FILE: src/app/(frontend)/(pages)/community-help/(posts)/github/[slug]/page.tsx
type DateFromSource (line 15) | type DateFromSource = string
function generateStaticParams (line 75) | async function generateStaticParams() {
function generateMetadata (line 90) | async function generateMetadata({
FILE: src/app/(frontend)/(pages)/docs/[topic]/[doc]/page.tsx
type Params (line 12) | type Params = { doc: string; topic: string }
function DocsPage (line 14) | async function DocsPage({ params }: { params: Promise<Params> }) {
function generateMetadata (line 52) | async function generateMetadata({ params }: { params: Promise<Params> }) {
function generateStaticParams (line 98) | async function generateStaticParams(): Promise<Params[]> {
FILE: src/app/(frontend)/(pages)/docs/dynamic/[topic]/[doc]/layout.tsx
function Layout (line 10) | async function Layout({ children }: { children: React.ReactNode }) {
FILE: src/app/(frontend)/(pages)/docs/dynamic/[topic]/[doc]/page.tsx
type TopicsOrder (line 16) | type TopicsOrder = { topics: string[] }[]
type Params (line 18) | type Params = { doc: string; topic: string }
function DocsPage (line 20) | async function DocsPage(args: {
FILE: src/app/(frontend)/(pages)/docs/local/[topic]/[doc]/layout.tsx
function Layout (line 10) | async function Layout({ children }: { children: React.ReactNode }) {
FILE: src/app/(frontend)/(pages)/docs/local/[topic]/[doc]/page.tsx
type TopicsOrder (line 16) | type TopicsOrder = { topics: string[] }[]
type Params (line 18) | type Params = { doc: string; topic: string }
function DocsPage (line 20) | async function DocsPage(args: {
FILE: src/app/(frontend)/(pages)/docs/v2/[topic]/[doc]/page.tsx
type TopicsOrder (line 11) | type TopicsOrder = { topics: string[] }[]
type Params (line 13) | type Params = { doc: string; topic: string }
function DocsPage (line 17) | async function DocsPage({ params }: { params: Promise<Params> }) {
function generateMetadata (line 65) | async function generateMetadata({
function generateStaticParams (line 116) | async function generateStaticParams(): Promise<Params[]> {
FILE: src/app/(frontend)/(pages)/layout.tsx
function Layout (line 10) | async function Layout({ children }: { children: React.ReactNode }) {
FILE: src/app/(frontend)/(pages)/partners/[slug]/page.tsx
function generateMetadata (line 25) | async function generateMetadata({ params }: { params: Promise<{ slug: st...
function PartnerPage (line 40) | async function PartnerPage({ params }: { params: Promise<{ slug: string ...
FILE: src/app/(frontend)/(pages)/partners/page.tsx
function Partners (line 23) | async function Partners() {
FILE: src/app/(frontend)/(pages)/posts/[category]/[slug]/page.tsx
function generateStaticParams (line 49) | async function generateStaticParams() {
function generateMetadata (line 67) | async function generateMetadata({
FILE: src/app/(frontend)/api/exit-preview/route.ts
function GET (line 3) | async function GET(): Promise<Response> {
FILE: src/app/(frontend)/api/locate/route.ts
function GET (line 87) | function GET(req: Request) {
FILE: src/app/(frontend)/api/og/route.tsx
function GET (line 8) | async function GET(req: NextRequest): Promise<ImageResponse> {
FILE: src/app/(frontend)/api/preview/route.ts
function GET (line 5) | async function GET(
FILE: src/app/(frontend)/api/revalidate/route.ts
function GET (line 6) | async function GET(request: NextRequest): Promise<NextResponse> {
FILE: src/app/(frontend)/api/star-count/route.ts
function GET (line 5) | async function GET(): Promise<NextResponse> {
FILE: src/app/(frontend)/api/sync-algolia/route.ts
function GET (line 5) | async function GET(): Promise<NextResponse> {
FILE: src/app/(frontend)/api/sync-ch/route.ts
function GET (line 11) | async function GET(): Promise<NextResponse> {
FILE: src/app/(frontend)/error.tsx
function Error (line 6) | function Error() {
FILE: src/app/(frontend)/layout.tsx
function RootLayout (line 15) | async function RootLayout({ children }: { children: React.ReactNode }) {
FILE: src/app/(frontend)/not-found.tsx
function NotFound (line 9) | async function NotFound() {
FILE: src/app/(frontend)/types.ts
type ProjectDeployResponse (line 3) | type ProjectDeployResponse = { team: Pick<Team, 'id' | 'slug'> } & Pick<
FILE: src/app/(payload)/admin/[[...segments]]/not-found.tsx
type Args (line 10) | type Args = {
FILE: src/app/(payload)/admin/[[...segments]]/page.tsx
type Args (line 10) | type Args = {
FILE: src/app/(payload)/api/[...slug]/route.ts
constant GET (line 14) | const GET = REST_GET(config)
constant POST (line 15) | const POST = REST_POST(config)
constant DELETE (line 16) | const DELETE = REST_DELETE(config)
constant PATCH (line 17) | const PATCH = REST_PATCH(config)
constant PUT (line 18) | const PUT = REST_PUT(config)
constant OPTIONS (line 19) | const OPTIONS = REST_OPTIONS(config)
FILE: src/app/(payload)/api/graphql-playground/route.ts
constant GET (line 7) | const GET = GRAPHQL_PLAYGROUND_GET(config)
FILE: src/app/(payload)/api/graphql/route.ts
constant POST (line 6) | const POST = GRAPHQL_POST(config)
constant OPTIONS (line 8) | const OPTIONS = REST_OPTIONS(config)
FILE: src/app/(payload)/layout.tsx
type Args (line 13) | type Args = {
FILE: src/app/_data/me.ts
constant USER (line 1) | const USER = `
constant ME_QUERY (line 18) | const ME_QUERY = `query {
FILE: src/app/_data/plans.ts
constant PLAN (line 1) | const PLAN = `
constant PLANS_QUERY (line 15) | const PLANS_QUERY = `
FILE: src/app/_data/project.ts
constant PROJECT (line 4) | const PROJECT = `
constant PROJECTS_QUERY (line 41) | const PROJECTS_QUERY = `
constant PROJECT_QUERY (line 55) | const PROJECT_QUERY = `
FILE: src/app/_data/team.ts
constant TEAM (line 1) | const TEAM = `id
constant TEAM_QUERY (line 16) | const TEAM_QUERY = `
constant TEAMS_QUERY (line 26) | const TEAMS_QUERY = `
FILE: src/app/_data/templates.ts
constant TEMPLATE_FIELDS (line 1) | const TEMPLATE_FIELDS = `
constant TEMPLATES (line 22) | const TEMPLATES = `
constant TEMPLATE_SLUGS (line 32) | const TEMPLATE_SLUGS = `
constant TEMPLATE (line 42) | const TEMPLATE = `
FILE: src/app/api/analytics/active-users/route.js
function GET (line 3) | async function GET(request) {
function getAccessToken (line 39) | async function getAccessToken(credentials) {
function fetchRealtimeData (line 82) | async function fetchRealtimeData(propertyId, accessToken) {
function pemToArrayBuffer (line 127) | function pemToArrayBuffer(pem) {
function base64UrlEncode (line 140) | function base64UrlEncode(data) {
FILE: src/app/api/analytics/channel-groups/route.js
function GET (line 3) | async function GET(request) {
function getAccessToken (line 39) | async function getAccessToken(credentials) {
function fetchChannelData (line 82) | async function fetchChannelData(propertyId, accessToken) {
function pemToArrayBuffer (line 134) | function pemToArrayBuffer(pem) {
function base64UrlEncode (line 147) | function base64UrlEncode(data) {
FILE: src/app/api/analytics/mockData.js
constant MOCK_ACTIVE_USERS (line 1) | const MOCK_ACTIVE_USERS = {
constant MOCK_ANALYTICS_METRICS (line 10) | const MOCK_ANALYTICS_METRICS = {
constant MOCK_CHANNEL_GROUPS (line 40) | const MOCK_CHANNEL_GROUPS = {
FILE: src/app/api/analytics/pageviews/route.js
function GET (line 3) | async function GET(request) {
function getAccessToken (line 39) | async function getAccessToken(credentials) {
function fetchGA4Data (line 82) | async function fetchGA4Data(propertyId, accessToken) {
function pemToArrayBuffer (line 221) | function pemToArrayBuffer(pem) {
function base64UrlEncode (line 234) | function base64UrlEncode(data) {
FILE: src/app/global-error.tsx
function GlobalError (line 6) | function GlobalError() {
FILE: src/collections/Docs/BranchButton/fetchAllBranches.ts
function fetchAllBranches (line 3) | async function fetchAllBranches(): Promise<
function parseLinkHeader (line 44) | function parseLinkHeader(header: string) {
FILE: src/collections/Docs/blocks/resource/index.ts
method export (line 13) | export({ fields }) {
method import (line 20) | import({ props }) {
FILE: src/collections/Docs/blocks/youtube/index.ts
method export (line 17) | export({ fields }) {
method import (line 25) | import({ props }) {
FILE: src/collections/Docs/index.ts
method fields (line 26) | fields({ defaultFields }) {
FILE: src/collections/Docs/mdxToLexical.ts
function mdxToLexical (line 73) | function mdxToLexical({
type FrontMatterData (line 117) | type FrontMatterData = {
FILE: src/collections/Docs/topicOrder.ts
type TopicOrder (line 3) | type TopicOrder = {
FILE: src/collections/Docs/types.ts
type GithubAPIResponse (line 1) | type GithubAPIResponse = {
type Heading (line 19) | type Heading = { anchor: string; level: number; text: string }
type ParsedDoc (line 21) | type ParsedDoc = {
type ParsedDocForNav (line 32) | type ParsedDocForNav = Pick<ParsedDoc, 'label' | 'order' | 'slug' | 'tit...
type Topic (line 34) | type Topic = { docs: ParsedDoc[]; label: string; slug: string }
type TopicForNav (line 36) | type TopicForNav = { docs: ParsedDocForNav[]; label: string; slug: string }
type TopicGroup (line 38) | type TopicGroup = {
type TopicGroupForNav (line 43) | type TopicGroupForNav = {
FILE: src/components/Accordion/index.tsx
type HeaderProps (line 31) | type HeaderProps = {
type ContentProps (line 47) | type ContentProps = {
type AccordionProps (line 60) | type AccordionProps = {
FILE: src/components/AuthorTag/index.tsx
type Props (line 19) | type Props = {
FILE: src/components/BackgroundGradient/index.tsx
type BackgroundGradientProps (line 5) | type BackgroundGradientProps = {
function BackgroundGradient (line 9) | function BackgroundGradient(props: BackgroundGradientProps) {
FILE: src/components/BackgroundGrid/index.tsx
type GridLineStyles (line 5) | type GridLineStyles = {
type Props (line 9) | type Props = {
FILE: src/components/BackgroundScanline/index.tsx
type Props (line 8) | interface Props {
FILE: src/components/Banner/index.tsx
type Props (line 9) | type Props = {
FILE: src/components/BigThree/index.tsx
type BigThreeProps (line 3) | interface BigThreeProps {
FILE: src/components/BlockSpacing/index.tsx
type Props (line 5) | type Props = {
FILE: src/components/BlockWrapper/index.tsx
type Settings (line 10) | type Settings = Extract<
type PaddingProps (line 15) | type PaddingProps = {
type Props (line 20) | type Props = {
FILE: src/components/BorderBox/index.tsx
type Props (line 5) | type Props = {
FILE: src/components/Breadcrumbs/index.tsx
type Breadcrumb (line 7) | type Breadcrumb = {
type Props (line 12) | type Props = {
FILE: src/components/Button/index.tsx
type ButtonProps (line 19) | type ButtonProps = {
type GenerateSlugType (line 80) | type GenerateSlugType = {
FILE: src/components/CMSForm/Label/types.ts
type Props (line 3) | interface Props extends HTMLAttributes<HTMLLabelElement> {
FILE: src/components/CMSForm/Submit/index.tsx
type SubmitProps (line 9) | type SubmitProps = {
FILE: src/components/CMSForm/fields/Select/index.tsx
type Option (line 15) | type Option = {
type SelectProps (line 20) | type SelectProps = {
FILE: src/components/CMSLink/index.tsx
type PageReference (line 14) | type PageReference = {
type PostsReference (line 19) | type PostsReference = {
type CaseStudyReference (line 24) | type CaseStudyReference = {
type LinkType (line 29) | type LinkType = 'custom' | 'reference' | null
type Reference (line 30) | type Reference = CaseStudyReference | null | PageReference | PostsReference
type CMSLinkType (line 32) | type CMSLinkType = {
type GenerateSlugType (line 50) | type GenerateSlugType = {
FILE: src/components/ChangeHeaderTheme/index.tsx
type ThemeHeaderProps (line 8) | type ThemeHeaderProps = {
FILE: src/components/Code/types.ts
type CodeFeatureBlock (line 3) | type CodeFeatureBlock = Extract<Page['layout'][0], { blockType: 'codeFea...
type CodeBlips (line 5) | type CodeBlips = NonNullable<CodeFeatureBlock['codeFeatureFields']['code...
type CodeBlip (line 7) | type CodeBlip = NonNullable<CodeBlips>[number]
type Props (line 9) | interface Props {
FILE: src/components/CodeBlip/CodeBlipContext.tsx
type CodeBlipContextType (line 6) | type CodeBlipContextType = {
FILE: src/components/ContributionTable/index.tsx
type ContributionTableProps (line 8) | type ContributionTableProps = {
FILE: src/components/CopyToClipboard/index.tsx
type CopyToClipboardProps (line 8) | type CopyToClipboardProps = {
FILE: src/components/CreatePayloadApp/index.tsx
type Props (line 8) | type Props = {
FILE: src/components/DiscordGitComments/index.tsx
type CommentProps (line 16) | type CommentProps = {
FILE: src/components/DiscordGitIntro/index.tsx
type Props (line 11) | type Props = {
FILE: src/components/Drawer/types.ts
type Props (line 3) | interface Props {
type TogglerProps (line 14) | type TogglerProps = {
FILE: src/components/DropdownMenu/MenuContent/index.tsx
type Props (line 5) | type Props = {
FILE: src/components/DropdownMenu/index.tsx
type MenuProps (line 7) | type MenuProps = {
FILE: src/components/FileAttachment/index.tsx
type Props (line 9) | type Props = {
FILE: src/components/GuestSocials/index.tsx
type GuestSocialProps (line 5) | type GuestSocialProps = {
FILE: src/components/Gutter/index.tsx
type Props (line 5) | type Props = {
FILE: src/components/Header/DesktopNav/index.tsx
type DesktopNavType (line 19) | type DesktopNavType = { hideBackground?: boolean } & Pick<MainMenu, 'men...
FILE: src/components/Header/Docsearch/Component.tsx
function Hit (line 7) | function Hit({ children, hit, path }) {
function Component (line 23) | function Component() {
FILE: src/components/Header/MobileNav/index.tsx
type NavItems (line 29) | type NavItems = Pick<MainMenu, 'menuCta' | 'tabs'>
FILE: src/components/Heading/index.tsx
type HeadingType (line 6) | type HeadingType = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
type Props (line 8) | type Props = {
FILE: src/components/Hero/BreadcrumbsBar/index.tsx
type HeroProps (line 15) | interface HeroProps {
type LinksProps (line 20) | interface LinksProps {
type Conditional (line 25) | type Conditional = HeroProps | LinksProps
type Props (line 27) | type Props = {
FILE: src/components/Hero/FormHero/index.tsx
type FormHeroProps (line 17) | type FormHeroProps = Page['hero']
FILE: src/components/Hero/Home/LogoShowcase/index.tsx
type LogoItem (line 9) | type LogoItem = {
type PositionedLogo (line 14) | type PositionedLogo = {
type Props (line 20) | type Props = {
constant TOTAL_CELLS (line 24) | const TOTAL_CELLS = 12
constant ANIMATION_DURATION (line 25) | const ANIMATION_DURATION = 650 // Duration for fade-out and fade-in in m...
constant ANIMATION_DELAY (line 26) | const ANIMATION_DELAY = 650 // Delay between animations in milliseconds
FILE: src/components/Hero/HomeNew/LogoShowcase/index.tsx
type LogoItem (line 10) | type LogoItem = MediaType
FILE: src/components/Indicator/index.tsx
type IndicatorProps (line 6) | type IndicatorProps = {
FILE: src/components/MDX/components/TableWithDrawers/index.tsx
type Props (line 7) | type Props = {
FILE: src/components/MaxWidth/index.tsx
type Props (line 5) | type Props = {
FILE: src/components/Media/types.ts
type Props (line 5) | interface Props {
FILE: src/components/MediaParallax/index.tsx
type ParallaxProps (line 10) | type ParallaxProps = {
FILE: src/components/MediaStack/index.tsx
type MediaStackProps (line 8) | type MediaStackProps = {
FILE: src/components/ModalWindow/index.tsx
type ModalWindowProps (line 8) | type ModalWindowProps = {
FILE: src/components/NewsletterSignUp/index.tsx
type NewsletterSignUpProps (line 13) | interface NewsletterSignUpProps {
FILE: src/components/PartnerDirectory/index.tsx
type FilterablePartner (line 15) | type FilterablePartner = {
FILE: src/components/PartnerGrid/index.tsx
type PartnerGridProps (line 7) | type PartnerGridProps = {
FILE: src/components/Payload3D/index.tsx
type Payload3DProps (line 8) | interface Payload3DProps {}
FILE: src/components/PayloadRedirects/index.tsx
type Props (line 8) | interface Props {
FILE: src/components/RelatedHelpList/index.tsx
type Props (line 10) | type Props = {
FILE: src/components/RelatedResources/index.tsx
type RelatedResourcesProps (line 10) | type RelatedResourcesProps = {
FILE: src/components/RenderBlocks/index.tsx
type ReusableContentBlockType (line 42) | type ReusableContentBlockType = Extract<Page['layout'][0], { blockType: ...
type BlocksProp (line 76) | type BlocksProp = RelatedPostsBlock | ReusableContent['layout'][0] | Reu...
type Props (line 78) | type Props = {
FILE: src/components/RenderBlocks/utilities.ts
function getFieldsKeyFromBlock (line 6) | function getFieldsKeyFromBlock(block: BlocksProp): string {
FILE: src/components/RenderDocs/index.tsx
type DocsVersion (line 23) | type DocsVersion = 'beta' | 'current' | 'dynamic' | 'local' | 'v2'
FILE: src/components/RenderParams/Component.tsx
type Props (line 9) | type Props = {
FILE: src/components/RichText/Arrow/index.tsx
type ArrowProps (line 5) | interface ArrowProps {
FILE: src/components/RichText/BulletList/index.tsx
type BulletListItem (line 7) | interface BulletListItem {
type BulletListProps (line 12) | interface BulletListProps {
FILE: src/components/RichText/CustomTable/index.tsx
type Column (line 6) | type Column = {
type Props (line 14) | type Props = {
FILE: src/components/RichText/LightDarkImage/index.tsx
type Props (line 10) | type Props = {
FILE: src/components/RichText/Pill/index.tsx
type PillProps (line 5) | interface PillProps {
FILE: src/components/RichText/RestExamples/types.ts
type Example (line 3) | interface Example {
type Data (line 18) | interface Data {
type Props (line 26) | interface Props {
FILE: src/components/RichText/TableWithDrawers/index.tsx
type Props (line 10) | type Props = {
FILE: src/components/RichText/Upload/index.tsx
type RichTextUploadNodeType (line 10) | type RichTextUploadNodeType = {
type Props (line 19) | type Props = {
FILE: src/components/RichText/VideoDrawer/index.tsx
type Props (line 9) | type Props = {
FILE: src/components/RichText/context.tsx
type HeadingType (line 4) | type HeadingType = 'primary' | 'secondary' | 'tertiary'
type AddHeading (line 6) | type AddHeading = (anchor: string, heading: string, type: HeadingType) =...
type Heading (line 8) | interface Heading {
type IContext (line 14) | interface IContext {
FILE: src/components/RichText/formatAnchor.ts
function extractChildren (line 1) | function extractChildren(node: any): string {
FILE: src/components/RichText/index.tsx
type Props (line 71) | type Props = {
type NodeTypes (line 76) | type NodeTypes =
FILE: src/components/SimpleLogs/index.tsx
type MessageChunk (line 5) | type MessageChunk = {
type LogLine (line 9) | type LogLine = {
type Props (line 40) | type Props = {
function styleLogLine (line 112) | function styleLogLine(logLine: string): LogLine {
function styleLogs (line 178) | function styleLogs(logData: string): LogLine[] {
FILE: src/components/SocialIcon/index.tsx
type SocialIconProps (line 6) | type SocialIconProps = {
FILE: src/components/SplitAnimate/index.tsx
type Props (line 9) | interface Props {
FILE: src/components/SpotlightAnimation/index.tsx
type Props (line 9) | interface Props {
FILE: src/components/SpotlightAnimation/types.ts
type AllowedElements (line 3) | type AllowedElements = Extract<
FILE: src/components/TableOfContents/index.tsx
type Props (line 9) | type Props = {
FILE: src/components/TemplateCardsBlock/index.tsx
type TemplateCardType (line 7) | type TemplateCardType = NonNullable<Pick<TemplateCardsBlock, 'templates'...
FILE: src/components/Tooltip/TooltipContent/index.tsx
type Props (line 5) | type Props = {
FILE: src/components/Tooltip/index.tsx
type TooltipProps (line 6) | type TooltipProps = {
FILE: src/components/YouTube/index.tsx
type Props (line 5) | type Props = {
FILE: src/components/blocks/Banner/index.tsx
type BannerBlockProps (line 8) | type BannerBlockProps = Extract<ReusableContent['layout'][0], { blockTyp...
FILE: src/components/blocks/BlogContent/index.tsx
type Props (line 7) | type Props = Extract<ReusableContent['layout'][0], { blockType: 'blogCon...
FILE: src/components/blocks/BlogMarkdown/Block.tsx
type Props (line 14) | type Props = Extract<ReusableContent['layout'][0], { blockType: 'blogMar...
FILE: src/components/blocks/BlogMarkdown/index.tsx
function BlogMarkdown (line 6) | function BlogMarkdown(props) {
FILE: src/components/blocks/CallToAction/index.tsx
type CallToActionProps (line 22) | type CallToActionProps = {
FILE: src/components/blocks/Callout/index.tsx
type CalloutProps (line 19) | type CalloutProps = {
FILE: src/components/blocks/CardGrid/index.tsx
type CardGridProps (line 18) | type CardGridProps = {
FILE: src/components/blocks/CaseStudiesHighlight/index.tsx
type Props (line 14) | type Props = Extract<ReusableContent['layout'][0], { blockType: 'caseStu...
FILE: src/components/blocks/CaseStudyCards/index.tsx
type Props (line 17) | type Props = {
FILE: src/components/blocks/CaseStudyParallax/index.tsx
type ContentProps (line 18) | type ContentProps = Extract<Page['layout'][0], { blockType: 'caseStudyPa...
type Props (line 20) | type Props = {
type StickyBlockProps (line 26) | type StickyBlockProps = {
type QuoteProps (line 30) | type QuoteProps = {
FILE: src/components/blocks/CodeBlock/index.tsx
type Props (line 11) | type Props = Extract<ReusableContent['layout'][0], { blockType: 'code' }>
FILE: src/components/blocks/CodeFeature/index.tsx
type Props (line 22) | type Props = {
FILE: src/components/blocks/ComparisonTable/index.tsx
type ComparisonTableProps (line 11) | type ComparisonTableProps = {
FILE: src/components/blocks/Content/index.tsx
type Props (line 12) | type Props = {
FILE: src/components/blocks/ContentGrid/index.tsx
type ContentGridProps (line 13) | type ContentGridProps = {
type CellsProps (line 18) | type CellsProps = {
FILE: src/components/blocks/FormBlock/index.tsx
type FormBlockProps (line 16) | type FormBlockProps = {
FILE: src/components/blocks/HoverCards/index.tsx
type HoverCardsProps (line 18) | type HoverCardsProps = {
FILE: src/components/blocks/HoverHighlights/index.tsx
type HoverHighlightProps (line 15) | type HoverHighlightProps = {
FILE: src/components/blocks/LinkGrid/index.tsx
type LinkGridProps (line 17) | type LinkGridProps = {
type Fields (line 22) | type Fields = Exclude<LinkGridProps['linkGridFields'], undefined>
type Props (line 24) | type Props = Exclude<Fields['links'], null | undefined>[number]['link']
FILE: src/components/blocks/LogoGrid/index.tsx
type LogoItem (line 17) | type LogoItem = {
type PositionedLogo (line 22) | type PositionedLogo = {
type LogoGridProps (line 28) | type LogoGridProps = {
constant TOTAL_CELLS (line 33) | const TOTAL_CELLS = 8
constant ANIMATION_DURATION (line 34) | const ANIMATION_DURATION = 650 // Duration for fade-out and fade-in in m...
constant ANIMATION_DELAY (line 35) | const ANIMATION_DELAY = 650 // Delay between animations in milliseconds
FILE: src/components/blocks/MediaBlock/index.tsx
type Props (line 13) | type Props = {
FILE: src/components/blocks/MediaContent/index.tsx
type MediaContentProps (line 15) | type MediaContentProps = {
FILE: src/components/blocks/MediaContentAccordion/Desktop/index.tsx
type MediaContentAccordionProps (line 23) | type MediaContentAccordionProps = {
FILE: src/components/blocks/MediaContentAccordion/Mobile/index.tsx
type MediaContentAccordionProps (line 23) | type MediaContentAccordionProps = {
FILE: src/components/blocks/MediaContentAccordion/index.tsx
type MediaContentAccordionProps (line 13) | type MediaContentAccordionProps = {
FILE: src/components/blocks/Pricing/index.tsx
type Props (line 20) | type Props = {
FILE: src/components/blocks/RelatedPosts/index.tsx
type RelatedPostsBlock (line 8) | type RelatedPostsBlock = {
FILE: src/components/blocks/ReusableContent/index.tsx
type Props (line 6) | type Props = Extract<Page['layout'][0], { blockType: 'reusableContentBlo...
FILE: src/components/blocks/Slider/QuoteCard/index.tsx
type Props (line 10) | type Props = {
FILE: src/components/blocks/Slider/index.tsx
type Props (line 24) | type Props = {
FILE: src/components/blocks/Statement/index.tsx
type StatementProps (line 16) | type StatementProps = {
FILE: src/components/blocks/Steps/Step/index.tsx
type Props (line 12) | type Props = {
FILE: src/components/blocks/Steps/index.tsx
type Props (line 11) | type Props = Extract<Page['layout'][0], { blockType: 'steps' }>
FILE: src/components/blocks/StickyHighlights/Highlight/index.tsx
type StickyHighlightsProps (line 19) | type StickyHighlightsProps = Extract<Page['layout'][0], { blockType: 'st...
type Fields (line 21) | type Fields = Exclude<StickyHighlightsProps['stickyHighlightsFields'], u...
type Props (line 23) | type Props = {
FILE: src/components/blocks/StickyHighlights/index.tsx
type Props (line 14) | type Props = {
FILE: src/components/cards/PartnerCard/index.tsx
type PartnerCardProps (line 10) | type PartnerCardProps = Partner
FILE: src/components/cards/types.ts
type SharedProps (line 4) | interface SharedProps {
type SquareCardProps (line 11) | interface SquareCardProps extends SharedProps {
type ContentMediaCardProps (line 18) | interface ContentMediaCardProps extends SharedProps {
type PricingCardProps (line 27) | interface PricingCardProps extends SharedProps {
type DefaultCardProps (line 33) | interface DefaultCardProps extends SharedProps {
FILE: src/constants.ts
constant PRODUCTION_ENVIRONMENT_SLUG (line 1) | const PRODUCTION_ENVIRONMENT_SLUG = 'prod'
FILE: src/fields/blockFields.ts
type Args (line 5) | interface Args {
FILE: src/fields/link.ts
type LinkAppearances (line 20) | type LinkAppearances = 'default' | 'primary' | 'secondary'
type LinkType (line 22) | type LinkType = (options?: {
FILE: src/fields/linkGroup.ts
type LinkGroupType (line 8) | type LinkGroupType = (options?: {
FILE: src/fields/richText/features/label/LabelNode.ts
type SerializedLabelNode (line 21) | type SerializedLabelNode = Spread<
class LabelNode (line 29) | class LabelNode extends ElementNode {
method constructor (line 30) | constructor({ key }: { key?: NodeKey }) {
method clone (line 34) | static clone(node: LabelNode): LabelNode {
method getType (line 40) | static getType(): string {
method importJSON (line 44) | static importJSON(serializedNode: SerializedLabelNode): LabelNode {
method canBeEmpty (line 52) | canBeEmpty(): true {
method canInsertTextAfter (line 56) | canInsertTextAfter(): true {
method canInsertTextBefore (line 60) | canInsertTextBefore(): true {
method collapseAtStart (line 63) | collapseAtStart(): true {
method createDOM (line 71) | createDOM(config: EditorConfig): HTMLElement {
method exportDOM (line 77) | exportDOM(editor: LexicalEditor): DOMExportOutput {
method exportJSON (line 99) | exportJSON(): SerializedElementNode {
method insertNewAfter (line 106) | insertNewAfter(_: RangeSelection, restoreSelection?: boolean): Paragra...
method isInline (line 116) | isInline(): false {
method updateDOM (line 120) | updateDOM(prevNode: LabelNode, dom: HTMLElement): boolean {
function $createLabelNode (line 125) | function $createLabelNode(): LabelNode {
function $isLabelNode (line 129) | function $isLabelNode(node: LexicalNode | null | undefined): node is Lab...
FILE: src/fields/richText/features/largeBody/LargeBodyNode.ts
type SerializedLargeBodyNode (line 21) | type SerializedLargeBodyNode = Spread<
class LargeBodyNode (line 29) | class LargeBodyNode extends ElementNode {
method constructor (line 30) | constructor({ key }: { key?: NodeKey }) {
method clone (line 34) | static clone(node: LargeBodyNode): LargeBodyNode {
method getType (line 40) | static getType(): string {
method importJSON (line 44) | static importJSON(serializedNode: SerializedLargeBodyNode): LargeBodyN...
method canBeEmpty (line 52) | canBeEmpty(): true {
method canInsertTextAfter (line 56) | canInsertTextAfter(): true {
method canInsertTextBefore (line 60) | canInsertTextBefore(): true {
method collapseAtStart (line 63) | collapseAtStart(): true {
method createDOM (line 71) | createDOM(config: EditorConfig): HTMLElement {
method exportDOM (line 77) | exportDOM(editor: LexicalEditor): DOMExportOutput {
method exportJSON (line 99) | exportJSON(): SerializedElementNode {
method insertNewAfter (line 106) | insertNewAfter(_: RangeSelection, restoreSelection?: boolean): Paragra...
method isInline (line 116) | isInline(): false {
method updateDOM (line 120) | updateDOM(prevNode: LargeBodyNode, dom: HTMLElement): boolean {
function $createLargeBodyNode (line 125) | function $createLargeBodyNode(): LargeBodyNode {
function $isLargeBodyNode (line 129) | function $isLargeBodyNode(node: LexicalNode | null | undefined): node is...
FILE: src/fields/richText/index.ts
type RichText (line 4) | type RichText = (
FILE: src/fields/slug.ts
type Slug (line 6) | type Slug = (fieldToUse?: string, overrides?: Partial<Field>) => Field
FILE: src/forms/Error/types.ts
type Props (line 3) | interface Props extends HTMLAttributes<HTMLParagraphElement> {
FILE: src/forms/Form/index.tsx
type FormProps (line 22) | type FormProps = {
FILE: src/forms/Form/reducer.ts
function fieldReducer (line 55) | function fieldReducer(state: Fields, action: Action): Fields {
FILE: src/forms/Label/types.ts
type Props (line 3) | interface Props extends HTMLAttributes<HTMLLabelElement> {
FILE: src/forms/Submit/index.tsx
type SubmitProps (line 10) | type SubmitProps = {
FILE: src/forms/fields/Array/index.tsx
type ArrayRowProps (line 8) | type ArrayRowProps = {
type AddRowProps (line 37) | type AddRowProps = {
FILE: src/forms/fields/RadioGroup/index.tsx
type Option (line 12) | type Option = {
FILE: src/forms/fields/Secret/index.tsx
type SecretProps (line 15) | type SecretProps = {
FILE: src/forms/fields/Select/index.tsx
type Option (line 13) | type Option = {
type SelectProps (line 18) | type SelectProps = {
FILE: src/forms/fields/types.ts
type FieldProps (line 3) | interface FieldProps<T> {
FILE: src/forms/types.ts
type Validate (line 3) | type Validate = ((value: unknown) => boolean | string) | undefined
type Value (line 5) | type Value = any // eslint-disable-line @typescript-eslint/no-explicit-any
type Property (line 7) | interface Property {
type Data (line 11) | interface Data {
type OnSubmit (line 15) | interface OnSubmit {
type Field (line 27) | interface Field {
type InitialState (line 34) | interface InitialState {
type Fields (line 38) | interface Fields {
type SetModified (line 42) | interface SetModified {
type SetProcessing (line 46) | interface SetProcessing {
type SetSubmitted (line 50) | interface SetSubmitted {
type RESET (line 54) | interface RESET {
type REMOVE (line 59) | interface REMOVE {
type REMOVE_ROW (line 64) | interface REMOVE_ROW {
type FieldWithPath (line 70) | interface FieldWithPath extends Field {
type UPDATE (line 74) | interface UPDATE {
type Action (line 79) | type Action = REMOVE | REMOVE_ROW | RESET | UPDATE
type IFormContext (line 81) | interface IFormContext {
FILE: src/forms/useFormField/types.ts
type Options (line 3) | interface Options {
type SetValue (line 8) | type SetValue = (e: Value) => void
type FormField (line 10) | interface FormField<FieldValue> {
FILE: src/graphics/CalendarIcon/index.tsx
type Props (line 3) | type Props = {
FILE: src/graphics/CommentsIcon/index.tsx
type Props (line 3) | type Props = {
FILE: src/graphics/CommitIcon/index.tsx
type Props (line 3) | type Props = {
FILE: src/graphics/DiscordIcon/index.tsx
type Props (line 3) | type Props = {
FILE: src/graphics/DownloadIcon/index.tsx
type Props (line 3) | type Props = {
FILE: src/graphics/FilterIcon/index.tsx
type Props (line 3) | type Props = {
FILE: src/graphics/FullLogo/index.tsx
type FullLogoProps (line 3) | type FullLogoProps = React.ComponentPropsWithoutRef<'svg'>
FILE: src/graphics/GithubIcon/index.tsx
type Props (line 3) | type Props = {
FILE: src/graphics/InfoIcon/index.tsx
type Props (line 1) | type Props = {
FILE: src/graphics/SearchIcon/index.tsx
type Props (line 3) | type Props = {
FILE: src/graphics/SearchIconV2/index.tsx
type Props (line 3) | type Props = {
FILE: src/hooks/usePopulateDocument.ts
type UsePopulateDocumentOptions (line 8) | type UsePopulateDocumentOptions<T> = {
function usePopulateDocument (line 25) | function usePopulateDocument<T>({
FILE: src/icons/ChevronUpDownIcon/index.tsx
type Props (line 3) | type Props = {
FILE: src/icons/ExternalLinkIcon/index.tsx
type Props (line 3) | type Props = {
FILE: src/icons/QuoteIcon/index.tsx
type Props (line 3) | type Props = {
FILE: src/icons/QuoteIconAlt/index.tsx
type Props (line 3) | type Props = {
FILE: src/icons/TrashIcon/index.tsx
type Props (line 3) | type Props = {
FILE: src/icons/types.ts
type IconProps (line 1) | interface IconProps {
FILE: src/migrate.ts
function run (line 5) | async function run() {
FILE: src/migrations/20241116_194708_migration.ts
function up (line 4) | async function up({ payload, req }: MigrateUpArgs): Promise<void> {
function down (line 11) | async function down({ payload, req }: MigrateDownArgs): Promise<void> {
FILE: src/payload-cloud-types.ts
type Config (line 9) | interface Config {
type AtlasOrg (line 27) | interface AtlasOrg {
type AtlasProject (line 35) | interface AtlasProject {
type Project (line 43) | interface Project {
type Plan (line 224) | interface Plan {
type Team (line 250) | interface Team {
type User (line 281) | interface User {
type Template (line 318) | interface Template {
type Media (line 343) | interface Media {
type Deployment (line 355) | interface Deployment {
type Job (line 379) | interface Job {
type TeardownError (line 405) | interface TeardownError {
type FeatureFlag (line 421) | interface FeatureFlag {
FILE: src/payload-types.ts
type SupportedTimezones (line 15) | type SupportedTimezones =
type Config (line 64) | interface Config {
type UserAuthOperations (line 202) | interface UserAuthOperations {
type BlogContent (line 224) | interface BlogContent {
type BlogMarkdown (line 257) | interface BlogMarkdown {
type CodeExampleBlock (line 276) | interface CodeExampleBlock {
type MediaExampleBlock (line 286) | interface MediaExampleBlock {
type Media (line 296) | interface Media {
type Callout (line 319) | interface Callout {
type Cta (line 361) | interface Cta {
type Page (line 447) | interface Page {
type Post (line 779) | interface Post {
type Category (line 878) | interface Category {
type Code (line 896) | interface Code {
type CaseStudy (line 959) | interface CaseStudy {
type Partner (line 1027) | interface Partner {
type Region (line 1135) | interface Region {
type Specialty (line 1149) | interface Specialty {
type Budget (line 1163) | interface Budget {
type Industry (line 1177) | interface Industry {
type CardGrid (line 1191) | interface CardGrid {
type CaseStudyCards (line 1280) | interface CaseStudyCards {
type CaseStudiesHighlight (line 1320) | interface CaseStudiesHighlight {
type CaseStudyParallax (line 1354) | interface CaseStudyParallax {
type CodeFeature (line 1391) | interface CodeFeature {
type Content (line 1509) | interface Content {
type ContentGrid (line 1589) | interface ContentGrid {
type FormBlock (line 1669) | interface FormBlock {
type Form (line 1703) | interface Form {
type HoverCards (line 1883) | interface HoverCards {
type HoverHighlights (line 1943) | interface HoverHighlights {
type LinkGrid (line 2012) | interface LinkGrid {
type LogoGrid (line 2055) | interface LogoGrid {
type MediaBlock (line 2115) | interface MediaBlock {
type MediaContent (line 2150) | interface MediaContent {
type MediaContentAccordion (line 2218) | interface MediaContentAccordion {
type Pricing (line 2293) | interface Pricing {
type ReusableContentBlock (line 2351) | interface ReusableContentBlock {
type ReusableContent (line 2371) | interface ReusableContent {
type ComparisonTableType (line 2441) | interface ComparisonTableType {
type ExampleTabsBlock (line 2490) | interface ExampleTabsBlock {
type Slider (line 2534) | interface Slider {
type Statement (line 2624) | interface Statement {
type StepsBlock (line 2688) | interface StepsBlock {
type StickyHighlights (line 2725) | interface StickyHighlights {
type Doc (line 2830) | interface Doc {
type User (line 2882) | interface User {
type Link (line 2914) | interface Link {
type Command (line 2947) | interface Command {
type DownloadBlockType (line 2957) | interface DownloadBlockType {
type LightDarkImageBlock (line 2984) | interface LightDarkImageBlock {
type PayloadMediaBlock (line 2997) | interface PayloadMediaBlock {
type TableWithDrawersBlock (line 3008) | interface TableWithDrawersBlock {
type YoutubeBlock (line 3027) | interface YoutubeBlock {
type PillBlock (line 3037) | interface PillBlock {
type ArrowBlock (line 3050) | interface ArrowBlock {
type BulletListBlock (line 3060) | interface BulletListBlock {
type UploadBlock (line 3074) | interface UploadBlock {
type RestExamplesBlock (line 3100) | interface RestExamplesBlock {
type ResourceBlock (line 3154) | interface ResourceBlock {
type SpotlightBlock (line 3164) | interface SpotlightBlock {
type VideoBlock (line 3189) | interface VideoBlock {
type BrBlock (line 3199) | interface BrBlock {
type VideoDrawerBlock (line 3209) | interface VideoDrawerBlock {
type CommandLineBlock (line 3220) | interface CommandLineBlock {
type TemplateCardsBlock (line 3230) | interface TemplateCardsBlock {
type BannerBlock (line 3249) | interface BannerBlock {
type CodeBlock (line 3274) | interface CodeBlock {
type CommunityHelp (line 3307) | interface CommunityHelp {
type FormSubmission (line 3334) | interface FormSubmission {
type Redirect (line 3352) | interface Redirect {
type PayloadKv (line 3379) | interface PayloadKv {
type PayloadLockedDocument (line 3396) | interface PayloadLockedDocument {
type PayloadPreference (line 3479) | interface PayloadPreference {
type PayloadMigration (line 3502) | interface PayloadMigration {
type CaseStudiesSelect (line 3513) | interface CaseStudiesSelect<T extends boolean = true> {
type CommunityHelpSelect (line 3538) | interface CommunityHelpSelect<T extends boolean = true> {
type DocsSelect (line 3556) | interface DocsSelect<T extends boolean = true> {
type MediaSelect (line 3578) | interface MediaSelect<T extends boolean = true> {
type PagesSelect (line 3597) | interface PagesSelect<T extends boolean = true> {
type PostsSelect (line 3760) | interface PostsSelect<T extends boolean = true> {
type CategoriesSelect (line 3824) | interface CategoriesSelect<T extends boolean = true> {
type ReusableContentSelect (line 3837) | interface ReusableContentSelect<T extends boolean = true> {
type UsersSelect (line 3869) | interface UsersSelect<T extends boolean = true> {
type PartnersSelect (line 3896) | interface PartnersSelect<T extends boolean = true> {
type IndustriesSelect (line 3951) | interface IndustriesSelect<T extends boolean = true> {
type SpecialtiesSelect (line 3961) | interface SpecialtiesSelect<T extends boolean = true> {
type RegionsSelect (line 3971) | interface RegionsSelect<T extends boolean = true> {
type BudgetsSelect (line 3981) | interface BudgetsSelect<T extends boolean = true> {
type FormsSelect (line 3991) | interface FormsSelect<T extends boolean = true> {
type FormSubmissionsSelect (line 4127) | interface FormSubmissionsSelect<T extends boolean = true> {
type RedirectsSelect (line 4144) | interface RedirectsSelect<T extends boolean = true> {
type PayloadKvSelect (line 4160) | interface PayloadKvSelect<T extends boolean = true> {
type PayloadLockedDocumentsSelect (line 4168) | interface PayloadLockedDocumentsSelect<T extends boolean = true> {
type PayloadPreferencesSelect (line 4179) | interface PayloadPreferencesSelect<T extends boolean = true> {
type PayloadMigrationsSelect (line 4190) | interface PayloadMigrationsSelect<T extends boolean = true> {
type Footer (line 4200) | interface Footer {
type MainMenu (line 4240) | interface MainMenu {
type GetStarted (line 4422) | interface GetStarted {
type PartnerProgram (line 4503) | interface PartnerProgram {
type TopBar (line 4645) | interface TopBar {
type FooterSelect (line 4676) | interface FooterSelect<T extends boolean = true> {
type MainMenuSelect (line 4706) | interface MainMenuSelect<T extends boolean = true> {
type GetStartedSelect (line 4820) | interface GetStartedSelect<T extends boolean = true> {
type PartnerProgramSelect (line 4865) | interface PartnerProgramSelect<T extends boolean = true> {
type TopBarSelect (line 4922) | interface TopBarSelect<T extends boolean = true> {
type Auth (line 4943) | interface Auth {
type GeneratedTypes (line 4949) | interface GeneratedTypes extends Config {}
FILE: src/payload.config.ts
method fields (line 314) | fields({ defaultFields }) {
FILE: src/plugins/opsCounter.ts
type Args (line 5) | type Args = {
FILE: src/providers/Auth/index.tsx
type ResetPassword (line 8) | type ResetPassword = (args: {
type ForgotPassword (line 14) | type ForgotPassword = (args: { email: string }) => Promise<void>
type Create (line 16) | type Create = (args: { email: string; password: string; passwordConfirm:...
type Login (line 18) | type Login = (args: { email: string; password: string }) => Promise<User>
type Logout (line 20) | type Logout = () => Promise<void>
type AuthContext (line 22) | type AuthContext = {
constant CLOUD_CONNECTION_ERROR (line 34) | const CLOUD_CONNECTION_ERROR = 'An error occurred while attempting to co...
type UseAuth (line 276) | type UseAuth<T = User> = () => AuthContext
FILE: src/providers/ComputedCSSValues/index.tsx
type IComputedCSSValues (line 4) | interface IComputedCSSValues {
type Props (line 18) | type Props = {
FILE: src/providers/HeaderIntersectionObserver/index.tsx
type ContextT (line 12) | type ContextT = {
type HeaderIntersectionObserverProps (line 26) | type HeaderIntersectionObserverProps = {
FILE: src/providers/Privacy/index.tsx
type Privacy (line 6) | type Privacy = {
type CookieConsent (line 20) | type CookieConsent = {
FILE: src/providers/Theme/types.ts
type Theme (line 1) | type Theme = 'dark' | 'light'
type ThemePreferenceContextType (line 3) | interface ThemePreferenceContextType {
function themeIsValid (line 8) | function themeIsValid(string: null | string): string is Theme {
FILE: src/providers/ToastContainer/index.tsx
function ToastContainer (line 10) | function ToastContainer() {
FILE: src/scripts/clearDuplicateThreads.ts
function clearDuplicateThreads (line 4) | async function clearDuplicateThreads() {
FILE: src/scripts/fetchDiscord.ts
constant DISCORD_API_BASE (line 11) | const DISCORD_API_BASE = 'https://discord.com/api/v10'
type Thread (line 17) | type Thread = {
type Message (line 29) | type Message = {
type ExistingThread (line 43) | type ExistingThread = {
function segmentArray (line 49) | function segmentArray(array, segmentSize) {
function fetchFromDiscord (line 57) | async function fetchFromDiscord(
function processMessages (line 127) | function processMessages(messages: Message[]) {
function createSanitizedThread (line 162) | function createSanitizedThread(thread: Thread, messages: Message[]) {
function fetchDiscord (line 198) | async function fetchDiscord() {
FILE: src/scripts/fetchDocs.ts
function slugify (line 32) | function slugify(string: string): string {
function getHeadings (line 49) | function getHeadings(source: string): Heading[] {
function getLocalDocsPath (line 70) | function getLocalDocsPath(): string {
function getFilenames (line 79) | async function getFilenames({ topicSlug }): Promise<string[]> {
function getDocMatter (line 104) | async function getDocMatter({ docFilename, topicSlug }) {
function fetchDocs (line 128) | async function fetchDocs(args?: {
function fetchSingleDoc (line 196) | async function fetchSingleDoc(args: {
FILE: src/scripts/fetchGitHub.ts
type ExistingDiscussion (line 12) | type ExistingDiscussion = {
function fetchGitHub (line 17) | async function fetchGitHub(): Promise<void> {
FILE: src/scripts/generateLLMs.ts
function generateLLMs (line 7) | async function generateLLMs() {
FILE: src/scripts/syncToAlgolia.ts
type DiscordDoc (line 18) | interface DiscordDoc {
type GithubDoc (line 30) | interface GithubDoc {
FILE: src/ts-helpers/requireField.ts
type RequireField (line 1) | type RequireField<T, K extends keyof T> = Required<Pick<T, K>> & T
FILE: src/utilities/analytics.ts
function analyticsEvent (line 4) | function analyticsEvent(event: string, value?: unknown): void {
FILE: src/utilities/deepMerge.ts
function isObject (line 6) | function isObject(item: unknown): boolean {
function deepMerge (line 15) | function deepMerge(obj1, obj2) {
FILE: src/utilities/format-date-time.ts
type Args (line 61) | interface Args {
function formatDate (line 66) | function formatDate(args: Args): string {
FILE: src/utilities/generate-route-path.ts
type Args (line 3) | type Args = {
function generateRoutePath (line 10) | function generateRoutePath({
FILE: src/utilities/get-cookie.ts
function getCookie (line 1) | function getCookie(cookiename: string): string {
FILE: src/utilities/get-relative-date.ts
function getRelativeDate (line 1) | function getRelativeDate(incomingDate: Date): string {
FILE: src/utilities/getDocument.ts
type Collection (line 7) | type Collection = keyof Config['collections']
function getDocument (line 9) | async function getDocument(collection: Collection, slug: string, depth =...
FILE: src/utilities/getRedirects.ts
function getRedirects (line 5) | async function getRedirects(depth = 1) {
FILE: src/utilities/is-expanded-doc.ts
function isExpandedDoc (line 1) | function isExpandedDoc<T>(doc: string | T): doc is T {
FILE: src/utilities/isNumber.ts
function isNumber (line 1) | function isNumber(value: unknown): boolean {
FILE: src/utilities/isValidParamID.ts
function isValidParamID (line 4) | function isValidParamID(id: null | string): boolean {
FILE: src/utilities/merge-project-environment.ts
type Props (line 4) | type Props<ReturnProject = Project> = {
function mergeProjectEnvironment (line 8) | function mergeProjectEnvironment({ environmentSlug, project }: Props) {
FILE: src/utilities/parseCookies.ts
function parseCookies (line 1) | function parseCookies(cookieString: string): { [key: string]: string } {
FILE: src/utilities/qs.ts
function objectToQueryString (line 4) | function objectToQueryString(obj, parentKey = ''): string {
function stringToObject (line 25) | function stringToObject(str): { [key: string]: unknown } {
FILE: src/utilities/sanitizeSlug.ts
function sanitizeSlug (line 1) | function sanitizeSlug(string: string): string {
FILE: src/utilities/slugify.ts
function slugify (line 1) | function slugify(string: string): string {
FILE: src/utilities/use-cloud-api.ts
type UseCloudAPI (line 7) | type UseCloudAPI<R, A = null> = (args?: A) => {
type ProjectsData (line 128) | interface ProjectsData {
type ProjectWithTeam (line 179) | type ProjectWithTeam = {
FILE: src/utilities/use-debounce.ts
function useDebounce (line 3) | function useDebounce<T>(value: T, delay: number): T {
FILE: src/utilities/use-is-mounted.tsx
function useIsMounted (line 3) | function useIsMounted(): boolean {
FILE: src/utilities/use-popup-window.ts
type PopupMessage (line 5) | interface PopupMessage {
FILE: src/utilities/use-resize.ts
type Size (line 5) | interface Size {
type Resize (line 10) | interface Resize {
FILE: src/utilities/use-websocket.tsx
type WebSocketHookArgs (line 3) | type WebSocketHookArgs = {
FILE: src/utilities/useIntersection.ts
type Intersection (line 5) | interface Intersection {
Condensed preview — 1076 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (4,333K chars).
[
{
"path": ".github/workflows/on-payload-release.yml",
"chars": 776,
"preview": "name: on-payload-release\n\non:\n workflow_dispatch:\n repository_dispatch:\n types: [payload-release-event]\n\njobs:\n re"
},
{
"path": ".gitignore",
"chars": 500,
"preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n/src/docs\n\n# dependencies\n/node_m"
},
{
"path": ".prettierignore",
"chars": 146,
"preview": ".tmp\n**/.git\n**/.hg\n**/.pnp.*\n**/.svn\n**/.yarn/**\n**/build\n**/dist/**\n**/node_modules\n**/temp\ntsconfig.json\npayload-type"
},
{
"path": ".prettierrc.json",
"chars": 90,
"preview": "{\n \"singleQuote\": true,\n \"trailingComma\": \"all\",\n \"printWidth\": 100,\n \"semi\": false\n}\n"
},
{
"path": ".vscode/extensions.json",
"chars": 78,
"preview": "{\n \"recommendations\": [\"esbenp.prettier-vscode\", \"dbaeumer.vscode-eslint\"]\n}\n"
},
{
"path": ".vscode/settings.json",
"chars": 1124,
"preview": "{\n \"npm.packageManager\": \"pnpm\",\n \"editor.defaultFormatter\": \"esbenp.prettier-vscode\",\n \"[typescript]\": {\n \"editor"
},
{
"path": "Caddyfile",
"chars": 214,
"preview": "# Spin up the caddy server with `caddy run` or `yarn caddy`\n# this is useful to test the github oauth flow locally\n\npayl"
},
{
"path": "LICENSE",
"chars": 1064,
"preview": "MIT License\n\nCopyright (c) 2023 Payload\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof"
},
{
"path": "README.md",
"chars": 5629,
"preview": "# Payload Website\n\nThis is the repository for [Payload's official website](https://payloadcms.com/). It was built comple"
},
{
"path": "algolia.d.ts",
"chars": 535,
"preview": "// See https://github.com/epicweb-dev/epic-stack/discussions/247\n\ndeclare module 'react-instantsearch' {\n export { useP"
},
{
"path": "cssVariables.cjs",
"chars": 81,
"preview": "module.exports = {\n breakpoints: {\n s: 768,\n m: 1024,\n l: 1440,\n },\n}\n"
},
{
"path": "eslint.config.js",
"chars": 1673,
"preview": "import payloadEsLintConfig from '@payloadcms/eslint-config'\nimport payloadPlugin from '@payloadcms/eslint-plugin'\n\nexpor"
},
{
"path": "next-sitemap.config.cjs",
"chars": 148,
"preview": "module.exports = {\n siteUrl: process.env.SITEMAP_URL || 'https://payloadcms.com',\n generateRobotsTxt: true, // (option"
},
{
"path": "next.config.js",
"chars": 4519,
"preview": "import { withPayload } from '@payloadcms/next/withPayload'\nimport path from 'path'\nimport { fileURLToPath } from 'node:u"
},
{
"path": "package.json",
"chars": 3764,
"preview": "{\n \"name\": \"payload-website\",\n \"version\": \"1.0.4\",\n \"private\": true,\n \"type\": \"module\",\n \"scripts\": {\n \"dev\": \"c"
},
{
"path": "public/js/theme.js",
"chars": 22,
"preview": "console.log('script')\n"
},
{
"path": "public/llms-full.txt",
"chars": 1633952,
"preview": "# Payload Documentation\n\n# What is Payload?\n\nSource: https://payloadcms.com/docs/getting-started/what-is-payload\n\n\n<YouT"
},
{
"path": "public/llms.txt",
"chars": 10697,
"preview": "# Payload\n\n## Basics\n\n### Getting Started\n\n- [What is Payload?](https://payloadcms.com/docs/getting-started/what-is-payl"
},
{
"path": "public/robots.txt",
"chars": 120,
"preview": "# *\nUser-agent: *\nAllow: /\n\n# Host\nHost: https://payloadcms.com\n\n# Sitemaps\nSitemap: https://payloadcms.com/sitemap.xml\n"
},
{
"path": "public/sitemap-0.xml",
"chars": 203404,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" xmlns:news=\"http://ww"
},
{
"path": "public/sitemap.xml",
"chars": 188,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n<sitemap><loc>"
},
{
"path": "redirects.js",
"chars": 1295,
"preview": "import { formatPermalink } from './src/utilities/formatPermalink.js'\n\nexport const redirects = async () => {\n const sta"
},
{
"path": "src/access/isAdmin.ts",
"chars": 412,
"preview": "import type { Access, FieldAccess } from 'payload'\n\nexport const isAdmin: Access = ({ req: { user } }) => {\n // Return "
},
{
"path": "src/access/isAdminOrSelf.ts",
"chars": 705,
"preview": "import type { Access, FieldAccess } from 'payload'\n\nexport const isAdminOrSelf: Access = ({ req: { user } }) => {\n // N"
},
{
"path": "src/access/publishedOnly.ts",
"chars": 228,
"preview": "import type { Access } from 'payload'\n\nexport const publishedOnly: Access = ({ req: { user } }) => {\n if (user?.roles?."
},
{
"path": "src/access.ts",
"chars": 1152,
"preview": "import type { Project, User } from './payload-cloud-types'\n\nexport const checkRole = (allRoles: User['roles'], user: Use"
},
{
"path": "src/adapters/AlgoliaPagination/index.module.scss",
"chars": 2401,
"preview": "@use '@scss/common' as *;\n\n.pagination {\n display: flex;\n align-items: center;\n margin-top: 4rem;\n\n & > *:not(:last-"
},
{
"path": "src/adapters/AlgoliaPagination/index.tsx",
"chars": 3944,
"preview": "import { ChevronIcon } from '@root/icons/ChevronIcon/index'\nimport React from 'react'\nimport { usePagination } from 'rea"
},
{
"path": "src/adapters/AlgoliaSearchBox/index.module.scss",
"chars": 212,
"preview": "@use '@scss/common' as *;\n\n.algoliaSearchBox {\n @include label;\n & {\n font-size: inherit;\n padding: 0;\n borde"
},
{
"path": "src/adapters/AlgoliaSearchBox/index.tsx",
"chars": 1368,
"preview": "import useDebounce from '@root/utilities/use-debounce'\nimport React, { useCallback, useEffect } from 'react'\nimport { us"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/(tabs)/layout.tsx",
"chars": 1209,
"preview": "import { DashboardTabs } from '@cloud/_components/DashboardTabs/index'\nimport { cloudSlug } from '@cloud/slug'\nimport { "
},
{
"path": "src/app/(frontend)/(cloud)/cloud/(tabs)/page.module.scss",
"chars": 1224,
"preview": "@use '@scss/common' as *;\n\n.error {\n color: var(--theme-error-500);\n}\n\n.tabs {\n margin-bottom: 2rem;\n}\n\n.controls {\n "
},
{
"path": "src/app/(frontend)/(cloud)/cloud/(tabs)/page.tsx",
"chars": 798,
"preview": "import type { Metadata } from 'next'\n\nimport { mergeOpenGraph } from '@root/seo/mergeOpenGraph'\n\nimport { fetchMe } from"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/(tabs)/page_client.tsx",
"chars": 8031,
"preview": "'use client'\n\nimport type { Team, Template, User } from '@root/payload-cloud-types'\n\nimport { ProjectCard } from '@cloud"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/(tabs)/settings/DeletionConfirmationForm/index.tsx",
"chars": 3284,
"preview": "import { Button } from '@components/Button/index'\nimport { Heading } from '@components/Heading/index'\nimport { Message }"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/(tabs)/settings/DeletionConfirmationForm/page.module.scss",
"chars": 514,
"preview": "@use '@scss/common.scss' as *;\n\n.warning,\n.emailInput {\n margin-bottom: 1rem;\n}\n\n.modal {\n & > * {\n width: 800px;\n "
},
{
"path": "src/app/(frontend)/(cloud)/cloud/(tabs)/settings/layout.module.scss",
"chars": 741,
"preview": "@use '@scss/common.scss' as *;\n\n.gridWrap {\n margin-bottom: 4rem;\n}\n\n.sidebarNav {\n display: flex;\n flex-direction: c"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/(tabs)/settings/layout.tsx",
"chars": 1662,
"preview": "'use client'\n\nimport { cloudSlug } from '@cloud/slug'\nimport { EdgeScroll } from '@components/EdgeScroll/index'\nimport {"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/(tabs)/settings/page.module.scss",
"chars": 638,
"preview": "@use '@scss/common.scss' as *;\n\n.buttonWrap {\n display: flex;\n gap: 1rem;\n}\n\n.form {\n display: flex;\n flex-direction"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/(tabs)/settings/page.tsx",
"chars": 444,
"preview": "import type { Metadata } from 'next'\n\nimport { fetchMe } from '@cloud/_api/fetchMe'\nimport { mergeOpenGraph } from '@roo"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/(tabs)/settings/page_client.tsx",
"chars": 5528,
"preview": "'use client'\n\nimport type { OnSubmit } from '@forms/types'\nimport type { User } from '@root/payload-cloud-types'\n\nimport"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/(tabs)/teams/page.module.scss",
"chars": 735,
"preview": "@use '@scss/common.scss' as *;\n\n.introContent {\n padding-bottom: calc(var(--base) * 2);\n\n @include small-break {\n p"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/(tabs)/teams/page.tsx",
"chars": 2007,
"preview": "import type { Metadata } from 'next'\n\nimport { LinkGrid } from '@blocks/LinkGrid/index'\nimport { fetchMe } from '@cloud/"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/layout.tsx",
"chars": 1578,
"preview": "import { fetchTeamWithCustomer } from '@cloud/_api/fetchTeam'\nimport { DashboardTabs } from '@cloud/_components/Dashboar"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/page.module.scss",
"chars": 1530,
"preview": "@use '@scss/common' as *;\n\n.error {\n color: var(--theme-error-500);\n}\n\n.tabs {\n margin-bottom: 2rem;\n}\n\n.controls {\n "
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/page.tsx",
"chars": 1056,
"preview": "import type { Metadata } from 'next'\n\nimport { fetchProjects } from '@cloud/_api/fetchProjects'\nimport { fetchTeamWithCu"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/page_client.tsx",
"chars": 5730,
"preview": "'use client'\n\nimport type { ProjectsRes } from '@cloud/_api/fetchProjects'\nimport type { TeamWithCustomer } from '@cloud"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/billing/page.module.scss",
"chars": 293,
"preview": "@use '@scss/common.scss' as *;\n\n.description {\n a {\n color: var(--theme-blue-500);\n cursor: pointer;\n text-dec"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/billing/page.tsx",
"chars": 2818,
"preview": "import type { Metadata } from 'next'\n\nimport { SectionHeader } from '@cloud/[team-slug]/[project-slug]/(tabs)/settings/_"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/billing/useCustomerPortal.tsx",
"chars": 1952,
"preview": "import type { Team } from '@root/payload-cloud-types'\n\nimport { useRouter } from 'next/navigation'\nimport * as React fro"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/invoices/page.module.scss",
"chars": 1530,
"preview": "@use '@scss/common.scss' as *;\n\n.description {\n a {\n color: var(--theme-blue-600);\n cursor: pointer;\n text-dec"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/invoices/page.tsx",
"chars": 1453,
"preview": "import type { Metadata } from 'next'\n\nimport { SectionHeader } from '@cloud/[team-slug]/[project-slug]/(tabs)/settings/_"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/invoices/page_client.tsx",
"chars": 6039,
"preview": "'use client'\n\nimport type { InvoicesResult } from '@cloud/_api/fetchInvoices'\nimport type { TeamWithCustomer } from '@cl"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/invoices/useInvoices.ts",
"chars": 2894,
"preview": "import type { InvoicesResult } from '@cloud/_api/fetchInvoices'\nimport type { Team } from '@root/payload-cloud-types'\n\ni"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/members/UpdateRolesConfirmationForm/index.tsx",
"chars": 3474,
"preview": "import type { Member } from '@cloud/_components/TeamMembers/index'\nimport type { Team, User } from '@root/payload-cloud-"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/members/UpdateRolesConfirmationForm/page.module.scss",
"chars": 464,
"preview": "@use '@scss/common.scss' as *;\n\n.modal {\n & > * {\n width: 800px;\n overflow-x: scroll;\n max-height: 100vh;\n }\n"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/members/page.module.scss",
"chars": 305,
"preview": "@use '@scss/common.scss' as *;\n\n.description {\n a {\n color: var(--theme-blue-500);\n cursor: pointer;\n text-dec"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/members/page.tsx",
"chars": 745,
"preview": "import type { Metadata } from 'next'\n\nimport { fetchTeamWithCustomer } from '@cloud/_api/fetchTeam'\n\nimport { TeamMember"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/members/page_client.tsx",
"chars": 7784,
"preview": "'use client'\n\nimport type { TeamWithCustomer } from '@cloud/_api/fetchTeam'\nimport type { Member } from '@cloud/_compone"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/subscriptions/page.module.scss",
"chars": 1456,
"preview": "@use '@scss/common.scss' as *;\n\n.description {\n a {\n color: var(--theme-blue-500);\n cursor: pointer;\n text-dec"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/subscriptions/page.tsx",
"chars": 1616,
"preview": "import type { Metadata } from 'next'\n\nimport { SectionHeader } from '@cloud/[team-slug]/[project-slug]/(tabs)/settings/_"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/subscriptions/page_client.tsx",
"chars": 7238,
"preview": "'use client'\n\nimport type { SubscriptionsResult } from '@cloud/_api/fetchSubscriptions'\nimport type { TeamWithCustomer }"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/subscriptions/reducer.ts",
"chars": 563,
"preview": "import type { SubscriptionsResult } from '@cloud/_api/fetchSubscriptions'\n\nexport const subscriptionsReducer = (\n state"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/(tabs)/subscriptions/useSubscriptions.ts",
"chars": 5554,
"preview": "import type { Subscription, SubscriptionsResult } from '@cloud/_api/fetchSubscriptions'\nimport type { Team } from '@root"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/TeamBillingMessages/index.module.scss",
"chars": 129,
"preview": "@use '@scss/common.scss' as *;\n\n.billingMessages {\n margin-bottom: 2rem;\n\n @include mid-break {\n margin-bottom: 1re"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/TeamBillingMessages/index.tsx",
"chars": 1311,
"preview": "'use client'\n\nimport type { TeamWithCustomer } from '@cloud/_api/fetchTeam'\n\nimport { teamHasDefaultPaymentMethod } from"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/layout.module.scss",
"chars": 69,
"preview": "@use '@scss/common.scss' as *;\n\n.gridWrap {\n margin-bottom: 4rem;\n}\n"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/layout.tsx",
"chars": 1662,
"preview": "import { fetchTeamWithCustomer } from '@cloud/_api/fetchTeam'\nimport { Sidebar } from '@cloud/_components/Sidebar/index'"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/page.module.scss",
"chars": 250,
"preview": "@use '@scss/common.scss' as *;\n\n.error {\n color: var(--theme-error-500);\n}\n\n.success {\n color: var(--theme-success-500"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/page.tsx",
"chars": 815,
"preview": "import type { Metadata } from 'next'\n\nimport { fetchTeamWithCustomer } from '@cloud/_api/fetchTeam'\nimport { mergeOpenGr"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/(tabs)/settings/page_client.tsx",
"chars": 3420,
"preview": "'use client'\n\nimport type { TeamWithCustomer } from '@cloud/_api/fetchTeam'\nimport type { OnSubmit } from '@forms/types'"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/(overview)/DeploymentLogs/index.module.scss",
"chars": 736,
"preview": "@use '@scss/common.scss' as *;\n\n.deploymentLogs {\n margin-top: 4rem;\n isolation: isolate;\n\n .logTabs {\n position: "
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/(overview)/DeploymentLogs/index.tsx",
"chars": 5550,
"preview": "import type { Tab } from '@cloud/_components/Tabs/index'\nimport type { LogLine } from '@components/SimpleLogs/index'\nimp"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/(overview)/InfraOffline/index.module.scss",
"chars": 2381,
"preview": "@use '@scss/common.scss' as *;\n\n.reTriggerBackground {\n display: flex;\n gap: 1.5rem;\n\n @include small-break {\n gap"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/(overview)/InfraOffline/index.tsx",
"chars": 11070,
"preview": "'use client'\n\nimport type { Project, Team } from '@root/payload-cloud-types'\nimport type { RequireField } from '@root/ts"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/(overview)/InfraOnline/index.module.scss",
"chars": 2439,
"preview": "@use '@scss/common.scss' as *;\n\n.deploymentWrapper {\n border: 1px solid var(--theme-border-color);\n\n p {\n margin: 0"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/(overview)/InfraOnline/index.tsx",
"chars": 10517,
"preview": "'use client'\n\nimport type { Deployment, Project } from '@root/payload-cloud-types'\n\nimport { BackgroundScanline } from '"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/(overview)/page.tsx",
"chars": 980,
"preview": "import type { Metadata } from 'next'\n\nimport { fetchProjectAndRedirect } from '@cloud/_api/fetchProject'\nimport { PRODUC"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/ProjectBillingMessages/BadSubscription.tsx",
"chars": 1302,
"preview": "'use client'\n\nimport type { ProjectWithSubscription } from '@cloud/_api/fetchProject'\nimport type { TeamWithCustomer } f"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/ProjectBillingMessages/MissingPaymentMethod.tsx",
"chars": 1151,
"preview": "'use client'\n\nimport type { ProjectWithSubscription } from '@cloud/_api/fetchProject'\nimport type { TeamWithCustomer } f"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/ProjectBillingMessages/TrialMessage.tsx",
"chars": 2776,
"preview": "'use client'\n\nimport type { ProjectWithSubscription } from '@cloud/_api/fetchProject'\nimport type { TeamWithCustomer } f"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/ProjectBillingMessages/index.module.scss",
"chars": 76,
"preview": "@use '@scss/common.scss' as *;\n\n.billingMessages {\n margin-bottom: 2rem;\n}\n"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/ProjectBillingMessages/index.tsx",
"chars": 2067,
"preview": "import type { ProjectWithSubscription } from '@cloud/_api/fetchProject'\nimport type { TeamWithCustomer } from '@cloud/_a"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/database/page.tsx",
"chars": 812,
"preview": "import type { Metadata } from 'next'\n\nimport { fetchProjectAndRedirect } from '@cloud/_api/fetchProject'\nimport { PRODUC"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/database/page_client.tsx",
"chars": 1288,
"preview": "'use client'\n\nimport type { Project, Team } from '@root/payload-cloud-types'\n\nimport { Banner } from '@components/Banner"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/file-storage/page.module.scss",
"chars": 1033,
"preview": "@use '@scss/common' as *;\n\n.fields {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.meta {\n list-style: no"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/file-storage/page.tsx",
"chars": 821,
"preview": "import type { Metadata } from 'next'\n\nimport { fetchProjectAndRedirect } from '@cloud/_api/fetchProject'\nimport { PRODUC"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/file-storage/page_client.tsx",
"chars": 3799,
"preview": "'use client'\n\nimport type { Project, Team } from '@root/payload-cloud-types'\n\nimport { Banner } from '@components/Banner"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/layout.tsx",
"chars": 4677,
"preview": "import type { Metadata } from 'next'\n\nimport { fetchProjectAndRedirect } from '@cloud/_api/fetchProject'\nimport { Dashbo"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/logs/page.tsx",
"chars": 799,
"preview": "import type { Metadata } from 'next'\n\nimport { fetchProjectAndRedirect } from '@cloud/_api/fetchProject'\nimport { PRODUC"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/logs/page_client.tsx",
"chars": 2013,
"preview": "'use client'\n\nimport type { LogLine } from '@components/SimpleLogs/index'\nimport type { Project, Team } from '@root/payl"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/(build-settings)/page.module.scss",
"chars": 114,
"preview": ".form {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n\n button[type='submit'] {\n width: auto;\n }\n}\n"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/(build-settings)/page.tsx",
"chars": 1515,
"preview": "import type { Metadata } from 'next'\n\nimport { fetchProjectAndRedirect } from '@cloud/_api/fetchProject'\nimport { PRODUC"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/(build-settings)/page_client.tsx",
"chars": 5195,
"preview": "'use client'\n\nimport type { Project, Team } from '@root/payload-cloud-types'\n\nimport { BranchSelector } from '@cloud/_co"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/_layoutComponents/NoData/index.module.scss",
"chars": 173,
"preview": ".noData {\n padding: 1rem;\n background-color: var(--theme-elevation-50);\n border: 1px solid var(--theme-border-color);"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/_layoutComponents/NoData/index.tsx",
"chars": 223,
"preview": "import * as React from 'react'\n\nimport classes from './index.module.scss'\n\ntype Props = {\n message: string\n}\nexport con"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/_layoutComponents/SectionHeader/index.module.scss",
"chars": 243,
"preview": ".sectionHeader {\n margin-bottom: 1.75rem;\n}\n\n.titleAndLink {\n display: flex;\n justify-content: space-between;\n align"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/_layoutComponents/SectionHeader/index.tsx",
"chars": 767,
"preview": "import { Button } from '@components/Button/index'\nimport { Heading } from '@components/Heading/index'\nimport * as React "
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/billing/page.module.scss",
"chars": 194,
"preview": "@use '@scss/common.scss' as *;\n\n.error {\n color: var(--theme-error-500);\n}\n\n.success {\n color: var(--theme-success-500"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/billing/page.tsx",
"chars": 5155,
"preview": "import type { Metadata } from 'next'\n\nimport { fetchMe } from '@cloud/_api/fetchMe'\nimport { fetchPaymentMethods } from "
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/domains/AddDomain/index.module.scss",
"chars": 270,
"preview": "@use '@scss/common' as *;\n\n.formContent {\n gap: 1rem;\n display: flex;\n flex-direction: column;\n}\n\n.actionFooter {\n d"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/domains/AddDomain/index.tsx",
"chars": 2766,
"preview": "'use client'\n\nimport type { OnSubmit } from '@forms/types'\nimport type { Project, Team } from '@root/payload-cloud-types"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/domains/ManageDomain/index.module.scss",
"chars": 1653,
"preview": "@use '@scss/common' as *;\n\n:global([data-theme='light']) {\n .configureDomain {\n background: var(--theme-elevation-10"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/domains/ManageDomain/index.tsx",
"chars": 4554,
"preview": "import type { Project, Team } from '@root/payload-cloud-types'\n\nimport { Accordion } from '@components/Accordion/index'\n"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/domains/page.tsx",
"chars": 1440,
"preview": "import { fetchProjectAndRedirect } from '@cloud/_api/fetchProject'\nimport { PRODUCTION_ENVIRONMENT_SLUG } from '@root/co"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/domains/page_client.tsx",
"chars": 2119,
"preview": "'use client'\n\nimport type { Project, Team } from '@root/payload-cloud-types'\n\nimport { Accordion } from '@components/Acc"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/email/AddEmailDomain/index.module.scss",
"chars": 270,
"preview": "@use '@scss/common' as *;\n\n.formContent {\n gap: 1rem;\n display: flex;\n flex-direction: column;\n}\n\n.actionFooter {\n d"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/email/AddEmailDomain/index.tsx",
"chars": 2791,
"preview": "'use client'\n\nimport type { OnSubmit } from '@forms/types'\nimport type { Project } from '@root/payload-cloud-types'\n\nimp"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/email/ManageEmailDomain/index.module.scss",
"chars": 2122,
"preview": "@use '@scss/common' as *;\n\n:global([data-theme='light']) {\n .configureDomain {\n background: var(--theme-elevation-10"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/email/ManageEmailDomain/index.tsx",
"chars": 9643,
"preview": "import type { ButtonProps } from '@components/Button/index'\nimport type { Project, Team } from '@root/payload-cloud-type"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/email/page.tsx",
"chars": 1147,
"preview": "import { fetchProjectAndRedirect } from '@cloud/_api/fetchProject'\nimport { PRODUCTION_ENVIRONMENT_SLUG } from '@root/co"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/email/page_client.tsx",
"chars": 4596,
"preview": "'use client'\n\nimport type { Plan, Project, Team } from '@root/payload-cloud-types'\n\nimport { cloudSlug } from '@cloud/sl"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/environment-variables/AddEnvs/index.module.scss",
"chars": 1031,
"preview": "@use '@scss/common' as *;\n\n.formContent {\n gap: 1rem;\n display: flex;\n flex-direction: column;\n}\n\n.newItemRow {\n dis"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/environment-variables/AddEnvs/index.tsx",
"chars": 3597,
"preview": "'use client'\n\nimport type { OnSubmit } from '@forms/types'\nimport type { Project } from '@root/payload-cloud-types'\n\nimp"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/environment-variables/ManageEnvs/index.module.scss",
"chars": 567,
"preview": "@use '@scss/common' as *;\n\n.accordionFormContent {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n\n textarea {"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/environment-variables/ManageEnvs/index.tsx",
"chars": 6926,
"preview": "'use client'\n\nimport type { Project } from '@root/payload-cloud-types'\n\nimport { revalidateCache } from '@cloud/_actions"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/environment-variables/Secret/index.tsx",
"chars": 1794,
"preview": "'use client'\n\nimport type { Project } from '@root/payload-cloud-types'\n\nimport { Accordion } from '@components/Accordion"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/environment-variables/page.module.scss",
"chars": 153,
"preview": "@use '@scss/common.scss' as *;\n\n.header {\n margin-bottom: 1rem;\n}\n\n.description {\n margin-bottom: 1.5rem;\n}\n\n.link {\n "
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/environment-variables/page.tsx",
"chars": 3622,
"preview": "import { fetchProjectAndRedirect } from '@cloud/_api/fetchProject'\nimport { Accordion } from '@components/Accordion/inde"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/environment-variables/validations.ts",
"chars": 468,
"preview": "export const validateKey = (key: string, existingKeys: string[]): string | true => {\n if (!key) {\n return 'Key is re"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/layout.module.scss",
"chars": 686,
"preview": "@use '@scss/common.scss' as *;\n\n.gridWrap {\n margin-bottom: 4rem;\n}\n\n.sidebarNav {\n display: flex;\n flex-direction: c"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/layout.tsx",
"chars": 2660,
"preview": "import { Sidebar } from '@cloud/_components/Sidebar/index'\nimport { Gutter } from '@components/Gutter/index'\nimport { PR"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/ownership/page.module.scss",
"chars": 656,
"preview": ".teamSelect {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n padding: 1.25rem 1rem;\n border: 1px solid var(-"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/ownership/page.tsx",
"chars": 1147,
"preview": "import { fetchProjectAndRedirect } from '@cloud/_api/fetchProject'\nimport { PRODUCTION_ENVIRONMENT_SLUG } from '@root/co"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/ownership/page_client.tsx",
"chars": 1775,
"preview": "'use client'\n\nimport type { Team } from '@root/payload-cloud-types'\n\nimport { MaxWidth } from '@components/MaxWidth/inde"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/plan/DeletePlanButton/index.tsx",
"chars": 401,
"preview": "'use client'\n\nimport { Button } from '@components/Button/index'\nimport { useModal } from '@faceless-ui/modal'\nimport Rea"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/plan/DeletePlanModal/index.module.scss",
"chars": 184,
"preview": ".modalActions {\n display: flex;\n gap: 1rem;\n justify-content: flex-end;\n width: 100%;\n padding-top: 1rem;\n border-"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/plan/DeletePlanModal/index.tsx",
"chars": 2942,
"preview": "'use client'\n\nimport type { Project } from '@root/payload-cloud-types'\n\nimport { Button } from '@components/Button/index"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/plan/index.module.scss",
"chars": 595,
"preview": ".plan {\n display: flex;\n flex-direction: column;\n gap: 3.5rem;\n}\n\n.borderBox {\n padding: 1.25rem;\n border: 1px soli"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/(tabs)/settings/plan/page.tsx",
"chars": 3371,
"preview": "import type { Plan } from '@root/payload-cloud-types'\nimport type { Metadata } from 'next'\n\nimport { fetchMe } from '@cl"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/configure/page.tsx",
"chars": 2121,
"preview": "import type { Metadata } from 'next'\n\nimport { fetchGitHubToken } from '@cloud/_api/fetchGitHubToken'\nimport { fetchInst"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/env/[environment-slug]/(tabs)/(overview)/page.tsx",
"chars": 137,
"preview": "import { metadata, default as OverviewPage } from '../../../../(tabs)/(overview)/page'\n\nexport default OverviewPage\n\nexp"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/env/[environment-slug]/(tabs)/ProjectBillingMessages/index.tsx",
"chars": 111,
"preview": "export { ProjectBillingMessages } from '@cloud/[team-slug]/[project-slug]/(tabs)/ProjectBillingMessages/index'\n"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/env/[environment-slug]/(tabs)/database/page.tsx",
"chars": 176,
"preview": "import {\n default as EnvironmentDatabase,\n metadata,\n} from '@cloud/[team-slug]/[project-slug]/(tabs)/database/page'\n\n"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/env/[environment-slug]/(tabs)/file-storage/page.tsx",
"chars": 186,
"preview": "import {\n default as EnvironmentFileStorage,\n metadata,\n} from '@cloud/[team-slug]/[project-slug]/(tabs)/file-storage/"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/env/[environment-slug]/(tabs)/layout.tsx",
"chars": 181,
"preview": "import {\n default as EnvironmentLayout,\n generateMetadata,\n} from '@cloud/[team-slug]/[project-slug]/(tabs)/layout'\n\ne"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/env/[environment-slug]/(tabs)/logs/page.tsx",
"chars": 164,
"preview": "import {\n default as EnvironmentLogs,\n metadata,\n} from '@cloud/[team-slug]/[project-slug]/(tabs)/logs/page'\n\nexport d"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/env/[environment-slug]/(tabs)/settings/(build-settings)/page.tsx",
"chars": 219,
"preview": "import {\n default as EnvironmentBuildSettings,\n generateMetadata,\n} from '@cloud/[team-slug]/[project-slug]/(tabs)/set"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/env/[environment-slug]/(tabs)/settings/billing/page.tsx",
"chars": 222,
"preview": "import {\n default as EnvironmentSettingsBillingPage,\n generateMetadata,\n} from '@cloud/[team-slug]/[project-slug]/(tab"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/env/[environment-slug]/(tabs)/settings/domains/page.tsx",
"chars": 222,
"preview": "import {\n default as EnvironmentSettingsDomainsPage,\n generateMetadata,\n} from '@cloud/[team-slug]/[project-slug]/(tab"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/env/[environment-slug]/(tabs)/settings/email/page.tsx",
"chars": 216,
"preview": "import {\n default as EnvironmentSettingsEmailPage,\n generateMetadata,\n} from '@cloud/[team-slug]/[project-slug]/(tabs)"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/env/[environment-slug]/(tabs)/settings/environment-variables/page.tsx",
"chars": 248,
"preview": "import {\n default as EnvironmentSettingsEnvManagementPage,\n generateMetadata,\n} from '@cloud/[team-slug]/[project-slug"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/env/[environment-slug]/(tabs)/settings/layout.tsx",
"chars": 154,
"preview": "import { default as EnvironmentSettingsLayout } from '@cloud/[team-slug]/[project-slug]/(tabs)/settings/layout'\n\nexport "
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/env/[environment-slug]/(tabs)/settings/ownership/page.tsx",
"chars": 228,
"preview": "import {\n default as EnvironmentSettingsOwnershipPage,\n generateMetadata,\n} from '@cloud/[team-slug]/[project-slug]/(t"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/[team-slug]/[project-slug]/env/[environment-slug]/(tabs)/settings/plan/page.tsx",
"chars": 213,
"preview": "import {\n default as EnvironmentSettingsPlanPage,\n generateMetadata,\n} from '@cloud/[team-slug]/[project-slug]/(tabs)/"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_actions/revalidateCache.ts",
"chars": 950,
"preview": "'use server'\n\nimport { revalidatePath, revalidateTag } from 'next/cache'\n\n// this will invalidate the Next.js `Client-Si"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_api/fetchGitHubToken.ts",
"chars": 1239,
"preview": "import type { Endpoints } from '@octokit/types'\n\ntype GitHubResponse = Endpoints['GET /user']['response']\n\nexport const "
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_api/fetchInstalls.ts",
"chars": 1967,
"preview": "import type { Endpoints } from '@octokit/types'\n\nimport { payloadCloudToken } from './token'\n\nexport type GitHubInstalla"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_api/fetchInvoices.ts",
"chars": 2002,
"preview": "import type { Team } from '@root/payload-cloud-types'\n\nimport { payloadCloudToken } from './token'\n\n// TODO: type this u"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_api/fetchMe.ts",
"chars": 1106,
"preview": "import type { User } from '@root/payload-cloud-types'\n\nimport { ME_QUERY } from '@data/me'\nimport { cookies } from 'next"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_api/fetchPaymentMethod.ts",
"chars": 953,
"preview": "import type { Team } from '@root/payload-cloud-types'\nimport type { PaymentMethod } from '@stripe/stripe-js'\n\nexport con"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_api/fetchPaymentMethods.ts",
"chars": 1788,
"preview": "import type { Team } from '@root/payload-cloud-types'\nimport type { PaymentMethod } from '@stripe/stripe-js'\n\nimport { p"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_api/fetchPlans.ts",
"chars": 617,
"preview": "import type { Plan } from '@root/payload-cloud-types'\n\nimport { PLANS_QUERY } from '@data/plans'\n\nexport const fetchPlan"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_api/fetchProject.ts",
"chars": 3568,
"preview": "import type { Project } from '@root/payload-cloud-types'\n\nimport { PROJECT_QUERY } from '@data/project'\nimport { mergePr"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_api/fetchProjects.ts",
"chars": 2756,
"preview": "import type { Project } from '@root/payload-cloud-types'\n\nimport { PROJECT_QUERY, PROJECTS_QUERY } from '@data/project'\n"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_api/fetchRepos.ts",
"chars": 2707,
"preview": "import type { Endpoints } from '@octokit/types'\n\nimport type { Install } from './fetchInstalls'\n\nimport { payloadCloudTo"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_api/fetchSubscriptions.ts",
"chars": 2310,
"preview": "import type { Project, Team } from '@root/payload-cloud-types'\n\nimport { payloadCloudToken } from './token'\n\n// TODO: ty"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_api/fetchTeam.ts",
"chars": 4016,
"preview": "import type { Team } from '@root/payload-cloud-types'\n\nimport { TEAM_QUERY, TEAMS_QUERY } from '@data/team'\nimport { not"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_api/fetchTemplate.ts",
"chars": 740,
"preview": "import type { Template } from '@root/payload-cloud-types'\n\nimport { TEMPLATE } from '@data/templates'\n\nexport const fetc"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_api/fetchTemplates.ts",
"chars": 900,
"preview": "import type { Template } from '@root/payload-cloud-types'\n\nimport { TEMPLATES } from '@data/templates'\n\nimport { payload"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_api/token.ts",
"chars": 55,
"preview": "export const payloadCloudToken = 'payload-cloud-token'\n"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_api/updateCustomer.ts",
"chars": 623,
"preview": "import type { Customer, TeamWithCustomer } from './fetchTeam'\n\nexport const updateCustomer = async (\n team: null | Team"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_api/updatePaymentMethod.ts",
"chars": 942,
"preview": "import type { Subscription } from '@cloud/_api/fetchSubscriptions'\n\nexport const updatePaymentMethod = async (args: {\n "
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_api/updateSubscription.ts",
"chars": 811,
"preview": "import type { ProjectWithSubscription } from './fetchProject'\nimport type { Subscription } from './fetchSubscriptions'\ni"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/BranchSelector/index.tsx",
"chars": 4992,
"preview": "import type { Endpoints } from '@octokit/types'\nimport type { Project } from '@root/payload-cloud-types'\n\nimport { Loadi"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/BranchSelector/reducer.ts",
"chars": 572,
"preview": "interface BranchState {\n branches: string[]\n defaultBranch: string\n}\n\ninterface BranchAction {\n payload: {\n branch"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/CloneOrDeployProgress/index.module.scss",
"chars": 2143,
"preview": "@use '@scss/common' as *;\n\n.deployProgress {\n color: var(--theme-elevation-400);\n padding: 2rem;\n background-color: v"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/CloneOrDeployProgress/index.tsx",
"chars": 3722,
"preview": "'use client'\n\nimport type { Install } from '@cloud/_api/fetchInstalls'\nimport type { Project, Template } from '@root/pay"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/CloudFooter/classes.module.scss",
"chars": 1599,
"preview": "@use '@scss/common' as *;\n\n.footerWrap {\n padding: 0 var(--gutter-h);\n height: var(--header-height);\n @include small;"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/CloudFooter/index.tsx",
"chars": 2919,
"preview": "'use client'\n\nimport type { Theme } from '@root/providers/Theme/types'\n\nimport { Gutter } from '@components/Gutter/index"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/CloudHeader/classes.module.scss",
"chars": 987,
"preview": "@use '@scss/common' as *;\n\n.wrapper {\n position: fixed;\n z-index: 100;\n top: 0;\n width: 100%;\n}\n\n.cloudHeader {\n di"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/CloudHeader/index.tsx",
"chars": 1722,
"preview": "'use client'\n\nimport type { TopBar as TopBarType } from '@root/payload-types'\n\nimport { TopBar } from '@components/TopBa"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/CloudLogo/classes.module.scss",
"chars": 233,
"preview": "@use '@scss/common' as *;\n\n.cloudLogo {\n display: flex;\n align-items: center;\n gap: calc(var(--base) / 2);\n\n svg {\n "
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/CloudLogo/index.tsx",
"chars": 265,
"preview": "import { PayloadIcon } from '@root/graphics/PayloadIcon/index'\n\nimport classes from './classes.module.scss'\n\nexport cons"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/ComparePlans/index.module.scss",
"chars": 1449,
"preview": "@use '@scss/common' as *;\n\n.drawerToggle {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n text-decoration: und"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/ComparePlans/index.tsx",
"chars": 2812,
"preview": "import type { Plan } from '@root/payload-cloud-types'\n\nimport { PricingCard } from '@components/cards/PricingCard/index'"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/CreditCardElement/index.module.scss",
"chars": 104,
"preview": "@use '@scss/common' as *;\n\n.cardElement {\n width: 100%;\n}\n\n.error {\n color: var(--theme-error-500);\n}\n"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/CreditCardElement/index.tsx",
"chars": 3073,
"preview": "import { useThemePreference } from '@root/providers/Theme/index'\nimport { CardElement as StripeCardElement } from '@stri"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/CreditCardList/index.module.scss",
"chars": 1823,
"preview": "@use '@scss/common' as *;\n\n.creditCardList {\n position: relative;\n}\n\n.scrollRef {\n position: absolute;\n top: -6rem;\n}"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/CreditCardList/index.tsx",
"chars": 6934,
"preview": "'use client'\n\nimport type { TeamWithCustomer } from '@cloud/_api/fetchTeam'\nimport type { PaymentMethod } from '@stripe/"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/CreditCardList/reducer.ts",
"chars": 681,
"preview": "import type { PaymentMethod } from '@stripe/stripe-js'\n\ninterface ADD_CARD {\n payload: PaymentMethod\n type: 'ADD_CARD'"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/CreditCardList/usePaymentMethods.ts",
"chars": 8297,
"preview": "import type { TeamWithCustomer } from '@cloud/_api/fetchTeam'\nimport type { PaymentMethod, SetupIntent } from '@stripe/s"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/CreditCardSelector/ProjectPaymentMethodSelector.tsx",
"chars": 1649,
"preview": "'use client'\n\nimport type { ProjectWithSubscription } from '@cloud/_api/fetchProject'\nimport type { TeamWithCustomer } f"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/CreditCardSelector/index.module.scss",
"chars": 936,
"preview": "@use '@scss/common' as *;\n\n.creditCardSelector {\n position: relative;\n}\n\n.scrollRef {\n position: absolute;\n top: -6re"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/CreditCardSelector/index.tsx",
"chars": 7179,
"preview": "import type { TeamWithCustomer } from '@cloud/_api/fetchTeam'\n\nimport { CreditCardElement } from '@cloud/_components/Cre"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/CreditCardSelector/useSubscription.ts",
"chars": 4094,
"preview": "import type { Team } from '@root/payload-cloud-types'\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/DashboardBreadcrumbs/index.module.scss",
"chars": 1361,
"preview": "@use '@scss/common' as *;\n\n.wrapper {\n display: flex;\n align-items: center;\n height: 100%;\n padding: 0;\n margin: 0;"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/DashboardBreadcrumbs/index.tsx",
"chars": 2561,
"preview": "'use client'\n\nimport { cloudSlug } from '@cloud/slug'\nimport { FullLogo } from '@root/graphics/FullLogo/index'\nimport Li"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/DashboardTabs/index.tsx",
"chars": 952,
"preview": "'use client'\n\nimport { usePathname } from 'next/navigation'\n\nimport type { Tab } from '../Tabs/index'\n\nimport { Tabs } f"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/InstallationButton/index.module.scss",
"chars": 227,
"preview": "@use '@scss/common' as *;\n\n.addAccountButton {\n background-color: transparent;\n margin: 0;\n padding: 0;\n border: non"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/InstallationButton/index.tsx",
"chars": 1010,
"preview": "import { usePopupWindow } from '@root/utilities/use-popup-window'\nimport React, { useState } from 'react'\n\nimport classe"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/InstallationSelector/components/MenuList/index.module.scss",
"chars": 269,
"preview": "@use '@scss/common' as *;\n\n.addAccountButton {\n display: block;\n background-color: transparent;\n margin: 0;\n padding"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/InstallationSelector/components/MenuList/index.tsx",
"chars": 517,
"preview": "import React from 'react'\nimport { components } from 'react-select'\n\nimport classes from './index.module.scss'\n\nexport c"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/InstallationSelector/components/Option/index.module.scss",
"chars": 337,
"preview": "@use '@scss/common' as *;\n\n.option {\n display: flex;\n align-items: center;\n overflow: hidden;\n}\n\n.githubIcon {\n disp"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/InstallationSelector/components/Option/index.tsx",
"chars": 472,
"preview": "import { GitHubIcon } from '@root/graphics/GitHub/index'\nimport { components } from 'react-select'\n\nimport classes from "
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/InstallationSelector/components/SingleValue/index.module.scss",
"chars": 337,
"preview": "@use '@scss/common' as *;\n\n.option {\n display: flex;\n align-items: center;\n overflow: hidden;\n}\n\n.githubIcon {\n disp"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/InstallationSelector/components/SingleValue/index.tsx",
"chars": 494,
"preview": "import { GithubIcon } from '@root/graphics/GithubIcon/index'\nimport { components } from 'react-select'\n\nimport classes f"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/InstallationSelector/index.module.scss",
"chars": 157,
"preview": "@use '@scss/common' as *;\n\n.description {\n @include small;\n & {\n margin-top: 0.5rem;\n color: var(--theme-elevati"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/InstallationSelector/index.tsx",
"chars": 3955,
"preview": "import type { Install } from '@cloud/_api/fetchInstalls'\n\nimport { LoadingShimmer } from '@components/LoadingShimmer/ind"
},
{
"path": "src/app/(frontend)/(cloud)/cloud/_components/InstallationSelector/types.ts",
"chars": 355,
"preview": "import type { Install } from '@cloud/_api/fetchInstalls'\n\nexport interface InstallationSelectorProps {\n className?: str"
}
]
// ... and 876 more files (download for full content)
About this extraction
This page contains the full source code of the payloadcms/website GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1076 files (3.9 MB), approximately 1.1M tokens, and a symbol index with 682 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.