Repository navigation
Correct publishing, retention, and traffic guidance #103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,21 +17,21 @@ Open the Space and go to **Settings → Stats**. A segmented control labelled ** | |
|
|
||
| Thirty days is the widest window. There is no longer one. | ||
|
|
||
| The page shows two totals, **Requests** and **Views**, then three sections. | ||
| The page shows **Requests**, **Visitor requests**, and **Visitors per day**. Visitor requests include assets, not only page loads. Visitors per day averages complete UTC days in the selected window. | ||
|
|
||
| | Section | What it lists | | ||
| | --- | --- | | ||
| | Traffic by period | One row per bucket, with requests, views, and bandwidth | | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ⚪️ Nit · Stats table still names the column "views" while the cards say "Visitor requests" The dashboard column is labeled "Visitor requests" ( Found by Indent Review Agent |
||
| | Unique visitors | Distinct visitors per day | | ||
| | Visitors | Daily distinct counts in the period table. The hourly window lists daily counts under the visitor card | | ||
| | Top paths | The busiest paths in the window | | ||
|
|
||
| Buckets are labelled in UTC, not your timezone, because that is the boundary the edge measured. Bandwidth is available in the table's field picker but hidden by default, since bandwidth is unlimited on every plan. | ||
| Buckets are labelled in UTC. Bandwidth is available in the table's field picker but hidden by default. Delivery has [plan allowances and usage rates](/usage). | ||
|
|
||
| ## What counts as a view | ||
|
|
||
| A **request** is any HTTP request the Space answered. A **view** is a request from something that is not a crawler with a status under 400, assets included. So `views` cannot exceed `requests`, and the gap comes from crawlers and responses with a status of 400 or higher. | ||
|
|
||
| **Unique visitors** come from a separate daily measurement. It ignores the crawler and status filters, and it merges every hostname mapped to the Space into one count. Daily is the finest resolution available, and days are never summed into a window total. That's why the page lists them one by one instead of showing a single number. | ||
| **Unique visitors** come from a separate daily measurement. It ignores the crawler and status filters, and it merges every hostname mapped to the Space into one count. Daily is the finest resolution available, and days are never summed into a window total. The dashboard shows daily counts and an average over complete days, rather than adding daily visitors into a window total. | ||
|
|
||
| **Top paths** and top hosts are capped at 10 entries each. | ||
|
|
||
|
|
@@ -74,6 +74,6 @@ curl "https://api.spacefast.com/v1/spaces/spc_xxxxxxxx/analytics?window=7d" \ | |
|
|
||
| There is no window-level request total in the payload. Sum `series[].requests` for it, which is what the dashboard does. | ||
|
|
||
| ## This is not Google Analytics | ||
| ## Add browser analytics | ||
|
|
||
| These numbers are the edge's own accounting, and they are all you get from Spacefast. If you want page-level product analytics, add your own tag. **Customization → Google Analytics** takes a GA4 measurement id or a Tag Manager container id and injects it into every published page. That is a separate feature with a separate switch. See [Customization](/customization). | ||
| For browser analytics, add your own tag. **Customization → Google Analytics** takes a GA4 measurement id or a Tag Manager container id. Its own switch controls whether the tag loads. See [Customization](/customization). | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -104,7 +104,7 @@ Every value here is recorded on the version. On GitHub Actions, GitLab CI, and B | |
|
|
||
| | Flag | Default | What it does | | ||
| | --- | --- | --- | | ||
| | `--show-secret` | off | Print the access URL and claim link in JSON or non-interactive output | | ||
| | `--show-secret` | off | Print secret fields, including the separate Space key. Anonymous preview and claim links are already included outside CI | | ||
| | `--allow-unsupported-platform-features` | off | Publish even when imported platform config includes features Spacefast cannot convert | | ||
|
|
||
| ## How publish decides what to do | ||
|
|
@@ -165,14 +165,14 @@ The team-wide default for future Spaces is `sf teams defaults`, on the [teams pa | |
|
|
||
| ## Anonymous publish and the claim key | ||
|
|
||
| With no login and no linked Space, publish creates an anonymous Space. It saves the key (`sfc_…`), claim URL, and expiry in `.spacefast/state.json`, which the CLI adds to `.gitignore`. The claim link prints once, on the publish that created the Space. Later publishes point at `sf spaces claim` instead. | ||
| With no login and no linked Space, publish creates an anonymous Space. It saves the key (`sfc_…`), claim URL, and expiry in `.spacefast/state.json`, which the CLI adds to `.gitignore`. Anonymous publish receipts include a preview URL, claim URL, expiry, and a message to relay to the person who will claim the Space. | ||
|
|
||
| ```bash | ||
| sf spaces claim # claim the Space saved here | ||
| sf continue # swap the key for a durable API key | ||
| ``` | ||
|
|
||
| In `--json` or non-interactive output the key, its URL form, and the claim URL are all `[REDACTED]` unless you pass `--show-secret`. The `expiresAt` field is never masked, so a script can always tell an anonymous receipt from a permanent one. The clock, the caps, and the claim itself are on [Publish without an account](/anonymous-and-claim). | ||
| Anonymous preview and claim links remain available in `--json` and non-interactive publish output so an agent can relay them. Both links contain the Space key. CI masks them unless you pass `--show-secret`; the separate `claim.key` field follows the CLI's secret-output policy. `expiresAt` remains visible. See [Publish without an account](/anonymous-and-claim) for deadlines and claiming. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For anonymous publishes using AGENTS.md reference: AGENTS.md:L15-L18 Useful? React with 👍 / 👎. |
||
|
|
||
| ## Examples | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,7 +5,7 @@ description: "This anonymous space expired before it was claimed." | |
|
|
||
| This anonymous space expired before it was claimed. | ||
|
|
||
| **How to resolve:** Publish a fresh space and share its claim link right away this time. If you meant to update a live space, check .spacefast/ (or your saved receipt) for its spaceId. Publish to that space with its credential instead of creating a new space. | ||
| **How to resolve:** Open the saved claim link to recover the Space while its recovery window is still open. If the Space has been purged, publish again and keep the new claim link. To update a different existing Space, select its spaceId and use its credential. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Bug · anonymous_expired fix is a hand edit to the exporter-owned snapshot and will be reverted AGENTS.md says Found by Indent Review Agent |
||
|
|
||
| <div data-pagefind-ignore> | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| --- | ||
| title: "domain_contact_identity_locked" | ||
| description: "Only the person who saved this contact can change its name, company name, or email address." | ||
| --- | ||
|
|
||
| Only the person who saved this contact can change its name, company name, or email address. | ||
|
|
||
| **How to resolve:** Ask them to make the change, or save a contact of your own. Other fields, like the address and phone, you can still edit. | ||
|
|
||
| <div data-pagefind-ignore> | ||
|
|
||
| ## Error shape | ||
|
|
||
| Every Spacefast API error is an RFC 9457 problem document, served as | ||
| `application/problem+json`. | ||
|
|
||
| - `code` is stable and machine-readable. | ||
| - `type` links to this page. | ||
| - `title` is a short label. | ||
| - `status` repeats the HTTP status. | ||
| - `detail` explains this occurrence. | ||
| - `pointer`, when present, is an RFC 6901 JSON Pointer at the offending field in the request body. | ||
| - `details`, when present, carries structured context. | ||
|
|
||
| Match on `code`, never on `detail`. | ||
|
|
||
| ```json | ||
| { | ||
| "type": "https://spacefast.com/docs/errors/domain_contact_identity_locked", | ||
| "title": "Domain contact identity locked", | ||
| "status": 400, | ||
| "detail": "Only the person who saved this contact can change its name, company name, or email address.", | ||
| "code": "domain_contact_identity_locked", | ||
| "requestId": "req_4mz0v8qk" | ||
| } | ||
| ``` | ||
|
|
||
| See the full list of error codes in the [error reference](/errors). | ||
|
|
||
| </div> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| --- | ||
| title: "domain_contact_not_owned" | ||
| description: "This contact belongs to someone else, so you can't register or move a domain to it." | ||
| --- | ||
|
|
||
| This contact belongs to someone else, so you can't register or move a domain to it. | ||
|
|
||
| **How to resolve:** Pass one of your own contacts (`viewerOwns: true` in listDomainContacts), or create one first. | ||
|
|
||
| <div data-pagefind-ignore> | ||
|
|
||
| ## Error shape | ||
|
|
||
| Every Spacefast API error is an RFC 9457 problem document, served as | ||
| `application/problem+json`. | ||
|
|
||
| - `code` is stable and machine-readable. | ||
| - `type` links to this page. | ||
| - `title` is a short label. | ||
| - `status` repeats the HTTP status. | ||
| - `detail` explains this occurrence. | ||
| - `pointer`, when present, is an RFC 6901 JSON Pointer at the offending field in the request body. | ||
| - `details`, when present, carries structured context. | ||
|
|
||
| Match on `code`, never on `detail`. | ||
|
|
||
| ```json | ||
| { | ||
| "type": "https://spacefast.com/docs/errors/domain_contact_not_owned", | ||
| "title": "Domain contact not owned", | ||
| "status": 400, | ||
| "detail": "This contact belongs to someone else, so you can't register or move a domain to it.", | ||
| "code": "domain_contact_not_owned", | ||
| "requestId": "req_4mz0v8qk" | ||
| } | ||
| ``` | ||
|
|
||
| See the full list of error codes in the [error reference](/errors). | ||
|
|
||
| </div> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| --- | ||
| title: "domain_contact_requires_person" | ||
| description: "Contacts belong to a person, and this credential acts as no one." | ||
| --- | ||
|
|
||
| Contacts belong to a person, and this credential acts as no one. | ||
|
|
||
| **How to resolve:** Team API keys act as the team, not a person. Sign in as yourself with `sf login`, or save the contact in the dashboard. | ||
|
|
||
| <div data-pagefind-ignore> | ||
|
|
||
| ## Error shape | ||
|
|
||
| Every Spacefast API error is an RFC 9457 problem document, served as | ||
| `application/problem+json`. | ||
|
|
||
| - `code` is stable and machine-readable. | ||
| - `type` links to this page. | ||
| - `title` is a short label. | ||
| - `status` repeats the HTTP status. | ||
| - `detail` explains this occurrence. | ||
| - `pointer`, when present, is an RFC 6901 JSON Pointer at the offending field in the request body. | ||
| - `details`, when present, carries structured context. | ||
|
|
||
| Match on `code`, never on `detail`. | ||
|
|
||
| ```json | ||
| { | ||
| "type": "https://spacefast.com/docs/errors/domain_contact_requires_person", | ||
| "title": "Domain contact requires person", | ||
| "status": 400, | ||
| "detail": "Contacts belong to a person, and this credential acts as no one.", | ||
| "code": "domain_contact_requires_person", | ||
| "requestId": "req_4mz0v8qk" | ||
| } | ||
| ``` | ||
|
|
||
| See the full list of error codes in the [error reference](/errors). | ||
|
|
||
| </div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Scope the renamed-slug reservation to the owning team.
The page states that slugs are unique per team and that two teams can own the same slug. As written, “Other Spaces” incorrectly includes Spaces in other teams and tells them to expect
slug_unavailable. Change this to “Other Spaces in that team” or document the global exception explicitly. (raw.githubusercontent.com)Proposed wording
Committable suggestion