With GitHub sync, your page lives in a pageo.json file in a GitHub repository. Each push to the main branch updates your page. GitHub sync is free.
Set up the repository
- On GitHub, create a public repository named
pageounder your own account, for examplegithub.com/yourname/pageo. - Add a
pageo.jsonfile at the root of themainbranch. Start from the example below. - Set
emailin the file to the email address of your pageo account. pageo checks it, so only you can link the repository.
Link it to pageo
- In your pageo admin sidebar, under Account, choose Link GitHub.
- Enter your GitHub username.
- pageo reads
pageo.jsonfrom your latest commit onmain. Your page content is replaced with the file's content.
After you link, the editor shows your page as synced from GitHub, and GitHub Settings in the sidebar holds the webhook setup.
Update on every push
- Open
github.com/yourname/pageo/settings/hooksand choose Add webhook. - Payload URL:
https://www.pageo.me/api/github/webhook - Content type:
application/json - Events: Just the push event.
- In pageo, open GitHub Settings, generate a secret, and paste the same secret in GitHub's Secret field.
- Choose Add webhook.
Pushes to other branches are ignored. The secret is optional, but without it pageo cannot confirm that a push came from GitHub.
Example pageo.json
{
"email": "you@example.com",
"profile": {
"name": "Maya Chen",
"role": "Product designer",
"bio": "I design calm software for small teams. **Booking for spring.**"
},
"socialLinks": [
{ "type": "github", "href": "https://github.com/mayachen" },
{ "type": "x", "href": "https://x.com/mayachen" },
{ "type": "linkedin", "href": "https://linkedin.com/in/mayachen" }
],
"gridLinks": [
{
"title": "Icon set",
"description": "120 calm interface icons",
"image": "https://example.com/icons.png",
"url": "https://mayachen.design/icons",
"layout": "grid",
"isPrimary": true
}
],
"settings": {
"layout": "grid",
"showContactForm": false
}
}
Field reference
Top level
| Field | Type | Required | Notes |
|---|---|---|---|
email | string | Yes | Must match your pageo account email. It is not shown on your page. |
profile | object | Yes | See below. |
socialLinks | array | Yes | Up to 12 items. Use [] for none. |
gridLinks | array | Yes | Any number of items. Use [] for none. |
settings | object | Yes | See below. |
profile
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | Yes | Your display name. |
role | string | Yes | The line under your name. |
bio | string | Yes | Markdown is supported. |
image | string | No | URL of your profile photo. |
email | string | No | A public contact email. |
socialLinks[]
| Field | Type | Required | Notes |
|---|---|---|---|
type | string | Yes | The icon, such as github, x, instagram, linkedin, youtube, or dribbble. |
href | string | Yes | The full URL. |
title | string | No | A label for the link. |
The order in the file is the order on your page.
gridLinks[]
| Field | Type | Required | Notes |
|---|---|---|---|
title | string | Yes | The card title. |
description | string | Yes | One line under the title. |
image | string | Yes | URL of the card image. |
url | string | Yes | Where the card links to. |
layout | grid, list, or minimal | Yes | The card style. |
isPrimary | boolean | No | Pins the card to lead your links. |
display | card or embed | No | embed shows a supported link as a player. See Players and embeds. |
kind | link, header, or text | No | header shows title as a section heading. text shows description as a note of up to 500 characters. Both ignore url and image, so set those to "". |
featured | boolean | No | Shows the link larger, across the full row. |
showFrom | string | No | An ISO time, such as 2026-11-01T09:00:00Z. The link shows from this time. pageo Pro. |
hideAfter | string | No | An ISO time. The link hides after this time. It must be after showFrom. pageo Pro. |
pageo numbers the links from their order in the file, so you never set id or order yourself.
settings
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
layout | list, grid, or minimal | Yes | The page layout. | |
showContactForm | boolean | Yes | Shows the contact form (pageo Pro). | |
allowAudienceSubscribe | boolean | No | false | Shows the subscribe button (pageo Pro). |
subscribeButtonLabel | string | No | Get updates | One of Get updates, Subscribe, Notify me, Stay updated. |
appendUtmParams | boolean | No | false | Adds UTM tags to outbound links. |
hideBranding | boolean | No | false | Hides the "Join <username> on pageo" badge (pageo Pro). |
profileMayContainNsfw | boolean | No | false | Shows a content warning before your page. |
seoTitle | string | No | Search result title (pageo Pro). | |
seoDescription | string | No | Search result description (pageo Pro). | |
mapEnabled | boolean | No | false | Shows the map section. |
mapLocation | string | No | City, State, Country, up to 100 characters. |
When a sync fails
pageo keeps your current page. When you link, the reason shows in the Link GitHub dialog. For a push, open the webhook on GitHub and check Recent Deliveries:
- Repo or pageo.json not found: check the repository name (
pageo), the branch (main), and that the file sits at the root. - Not valid JSON: run the file through a JSON validator. A trailing comma is the usual cause.
- Does not match the required schema: compare the file with the reference above. Every required field must be present.
- Email does not match: set
emailto your pageo account email.