Skip to content

Public project pages ​

A public project page is a build page anyone can open without a token or an account. Reach for it when a build should be findable by everyone who holds the link, not by one reviewer.

Quick start ​

Set the project's visibility to public in project settings:

console.extension.dev/<workspace>/<project>/project-settings/visibility

The project then answers at <workspace>.extension.dev/<project>, and every build, channel and version under it gets an address of its own.

How it works ​

The workspace lives in the host, not in a path segment, so a link carries the workspace identity before the page loads. Under the project root every page is a noun: a build, a browser's artifact, a channel, a version.

The per-browser build page is where strangers land. It offers the artifact as a zip, the executable downloads where the build produced them, and an Access tab titled What this build asks for. That tab lists each host pattern, permission and optional permission the manifest declares, with a line on what it unlocks.

The zip streams straight from the registry at registry.extension.land/<workspace>/<project>/builds/<buildId>/<browser>.zip as bytes with Content-Type: application/zip and no redirect, so a plain curl receives it. A public build's zip is cached as immutable for a year.

A project is either public or private, and the platform serves this page only for a project declared public. A project nobody declared is private. Two gates read the same declaration. The page gate hides the listing, the name, the icon and the changelog behind a card that names nothing. The registry gate answers 401 for the build bytes whether the file exists or not. A deny always wins, so a project declared private is refused even if an older allow entry is still around. A token scoped to the project opens both gates, so an owner's view keeps working while a stranger is turned away.

Making a project public exposes its listing and its builds. It does not expose build logs, store credentials or environment variables. Those never leave the console.

Visibility is a setting of the extension.dev project, not of its GitHub repository. Workspace owners and admins change it. Everyone else reads it. Changing it sets every channel's audience to match. A project connected through the console's onboard page starts with the visibility of its repository. A project created on /import starts private whatever its repository is. The platform re-declares the visibility to the registry on every completed build, so the declaration heals itself. The registry refreshes its lists about once a minute, so a change is not instant in either direction. Nothing recalls a file someone already downloaded.

Public does not mean indexed. The workspace subdomain refuses every search crawler in robots.txt and again with a noindex, nofollow tag on the page, so a public build page is reached by a link you send and not by a query someone types. Link preview bots are admitted by name, so a shared link unfurls where it lands: Twitterbot, facebookexternalhit, Slackbot, Slackbot-LinkExpanding, LinkedInBot, Discordbot, TelegramBot, WhatsApp, redditbot, Embedly, SkypeUriPreview, Mastodon and Bluesky. A private project unfurls to a card that names nothing, the same gate as the page.

A private project has no public project page. It shares one build with a build link, or a public channel with a channel link. See Build links and channel links. A member mints a token link with this call:

POST /api/projects/{id}/share

The call needs buildSha, or a scope that names a build, a channel or the whole project, and takes ttlHours. It returns a shareUrl carrying a ?share= token, with its expiry and its scope. Any workspace member may call it. It refuses a public project with 400, because a public project already has a page.

Reference ​

Path under the project rootContents
/builds/<buildId>One build, every browser it produced
/builds/<buildId>/whats-newWhat changed in that build
/builds/<buildId>/<browser>One artifact: zip download, executable downloads
/builds/<buildId>/<browser>/accessWhat this build asks for
/channels/<channel>What the channel currently holds
/<channel>Shortcut to the channel page
/versions/<version>A version across the builds that carried it
GateWhat it protectsWhat a stranger gets
The pageThe listing, the name, the icon, the changelogA card that names nothing
The registryThe build bytes401, whether the file exists or not
Share callValue
ttlHours7 days (168 hours) by default, from 1 hour up to the plan's share window: 30 days on Free, 365 days on Pro
buildShaPoints the link at /builds/<sha> and opens only that build
scope{kind: "build", name: "<sha>"}, {kind: "channel", name: "<channel>"} or {kind: "project"}. Without scope or buildSha, 400 SCOPE_REQUIRED
Public project400 "Project is public; share links are unnecessary."
Non-member403

When it fails ​

  • The page shows a brand card instead of your project: visibility is not public. That is the gate working. Set it under Visibility in project settings.
  • POST /api/projects/{id}/share answers 400: the project is public. Link the page itself.
  • A channel shortcut says the link does not resolve: the name is not a promoted channel of this project, or the link is out of date. Promote a build to that channel, or use the full /channels/<channel> form.
  • A share link says it has expired: a share token cannot be renewed. Mint a new one, or send a channel link, which never expires.
  • The page never appears in a search engine: it is not meant to. Send the address, or paste it somewhere a link preview renders it.

Next ​