Behio Storefront SDK
Advanced

Storefront repo

Clone the GitHub repo behind a Behio hosted storefront, run it locally and deploy by pushing

Every website Behio hosts for a shop lives in its own private GitHub repository under the Behio-Storefronts organisation, generated from a storefront template. It is a plain Next.js 16 app wired to @behio/storefront-sdk, so you can clone it, work on it locally and deploy by pushing.

Nothing of Behio's own source is in there. The repository holds only that one storefront.

All you need is a terminal and Node 22.

1. Get your commands from the admin

In the admin go to E-shop → Storefront, click Spravovat on the site you want and open the Lokální vývoj section. Vygenerovat přístupy a příkazy mints two things at once and renders the whole walkthrough as finished commands with your own values already in them:

  • a deploy key registered on this one repository only, with read and write access, so you can clone and push with it,
  • a public API key (pk_live_...) for the shop, which is what the site reads its products with.

Neither is stored in plaintext on our side, so both are shown exactly once, right after you generate. Generating again rotates the deploy key: the previous one is removed from the repository and stops working immediately.

Copy each block from the admin in order and paste it into a terminal. The sections below explain what those blocks do and why they look the way they do. Nothing here needs to be filled in by hand.

2. Save the deploy key

mkdir -p ~/.ssh
cat > ~/.ssh/behio_<repo> <<'BEHIO_KEY'
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
BEHIO_KEY
chmod 600 ~/.ssh/behio_<repo>

The heredoc delimiter is quoted (<<'BEHIO_KEY') so the shell leaves the key untouched, and a heredoc always writes the trailing newline that ssh demands. Without it ssh reports Load key: invalid format. The file is named after the repository so a merchant with several sites does not overwrite one key with the next.

3. Clone

git clone -b <branch> -c core.sshCommand="ssh -i ~/.ssh/behio_<repo> -o IdentitiesOnly=yes" [email protected]:Behio-Storefronts/<repo>.git
cd <repo>

-c core.sshCommand both authenticates this clone and persists into the new repo's .git/config, so every later git push uses the deploy key without you thinking about it.

Use core.sshCommand, not a Host github.com entry in ~/.ssh/config. A deploy key authorises a single repository. An ~/.ssh/config entry keyed on github.com applies to every GitHub remote on your machine, so ssh would offer the deploy key for your other projects and GitHub would answer Repository not found.

IdentitiesOnly=yes matters for the same reason in reverse: without it ssh first offers the keys already loaded in your agent, GitHub authenticates you as whoever that key belongs to, and the clone fails even though the deploy key is correct.

-b <branch> checks out the branch your site actually runs from (see section 5). Without it the clone lands on main, and on a preview site behio-draft is normally ahead of main, so your first push would be rejected as a non-fast-forward.

4. Write .env and run it

cat > .env <<'BEHIO_ENV'
BEHIO_API_KEY="pk_live_..."
NEXT_PUBLIC_BEHIO_API_KEY="pk_live_..."
BEHIO_API_URL="https://be.behio.com"
NEXT_PUBLIC_BEHIO_API_URL="https://be.behio.com"
NEXT_PUBLIC_SITE_URL="http://localhost:7010"
BEHIO_STOREFRONT_NOINDEX="1"
BEHIO_ENV
npm install --no-package-lock
npm run dev

The dev server listens on http://localhost:7010 and serves your shop's real data.

When something is wrong, the terminal says so. Storefronts generated from 2026-07-29 on print the reason into the terminal running npm run dev, and show it in a banner at the bottom of the page, in Czech: no API key in .env, a key the server rejected (401), an unreachable API, or a shop that is simply not launched yet. The banner exists only under npm run dev; a deployed site never renders it. Older repositories print nothing, which is why the .env block above matters: copy it whole, as printed.

VariableWhy
BEHIO_API_KEYThe shop's public API key. Server side reads and server actions.
NEXT_PUBLIC_BEHIO_API_KEYThe same key. It ships in the browser bundle and drives the client hooks.
BEHIO_API_URL / NEXT_PUBLIC_BEHIO_API_URLThe backend. Same value the deploy pipeline sets on the hosted app.
NEXT_PUBLIC_SITE_URLhttp://localhost:7010 locally. Canonical origin for SEO.
BEHIO_STOREFRONT_NOINDEXMarks the run as not a public production site, exactly like the sandbox application. Without it a shop you have not launched yet (Aktivní switched off) renders the maintenance page Připravujeme se instead of your site, and nothing anywhere says why.

Both key variables get the same public key on purpose. That is exactly what the deploy pipeline sets on the hosted app, so a local run sees the same data as production. A public key is publishable by design: the deployed site already ships that value in its browser bundle.

npm, not yarn. The template's package.json only defines plain next scripts and ships no lockfile, so npm resolves exactly the way the production Docker image does (it runs npm install too). --no-package-lock matters because the push step below is git add -A: a lockfile written here would land in your repository and pin @behio/storefront-sdk, which package.json deliberately floats as "*" so every build picks up the current SDK.

.env and .env.local are gitignored and the Docker build ignores them too, so they never reach the deployed site.

5. Push, and what a push deploys

A storefront can run as two applications from the same repository:

BranchApplicationAddress
mainproduction sitethe custom domain, or <slug>.behio.com
behio-draftsandbox preview<slug>-sandbox.behio.com

A push deploys on its own. Pushing to a branch rebuilds and redeploys the application that serves it, with nothing to click in the admin. It usually takes a minute or two. There is no webhook for you to set up: our GitHub organisation app forwards the push, and the deploy pipeline keeps auto deploy switched on for every application it provisions.

The catch is that this only works for a branch that has an application behind it. A shop that has never published a production site has no main application, only the sandbox, and a push to main there succeeds in git and deploys nothing, silently. This is why the clone in section 3 checks out the site's own branch and why the Lokální vývoj panel prints the push command for that branch: copy it from there rather than guessing.

npm run build                    # a build that fails is never deployed
git add -A
git commit -m "uprava webu"
git push origin HEAD:behio-draft # sandbox, every shop has this one
git push origin HEAD:main        # production, only once the shop is live

The build runs on Behio's infrastructure: npm install plus next build inside Docker, served with next start on port 3000 behind our proxy.

Feedback is coarse today. There is no build log in the admin and no progress bar. The site status shown in the admin tracks only the deploys started from the admin, so it stays on its previous value through a push triggered build even while the site is being rebuilt: check the site itself for the result. Use Přepublikovat in the same panel when you want a deploy whose status is reported back in the admin.

6. What else writes to your repository

The AI site editor in the admin commits to the same repository:

  • AI edits are committed to behio-draft,
  • Publikovat merges behio-draft into main and deploys,
  • Vrátit and Vrátit publikaci move the branch by force to an older commit.

A force move can drop commits you pushed. Pull before you start, push finished work promptly, and do not run the AI editor on a site while you are working on its repository.

The deploy pipeline itself does not rewrite your files. Runtime configuration (BEHIO_API_KEY, NEXT_PUBLIC_SITE_URL, indexing flags) is set on the hosted application on every deploy, not in the repository, so committing an .env changes nothing about the live site.

Keep the repository root layout intact: the build expects Dockerfile at the root and an app that listens on port 3000 in production.

Troubleshooting

SymptomCause
Locally you get Připravujeme se / Obchod je právě v údržbě instead of the shopThe shop is not launched yet (Aktivní off), and the local run was missing BEHIO_STOREFRONT_NOINDEX="1", which is what tells the site it is not a public production deployment. Add that line to .env and restart. Nothing is wrong with your key or your repository.
The site loads but is called Store and has no productsThe API key was rejected or the API was unreachable. Read the terminal running npm run dev: it names which of the two happened. Most often the key was rotated in the admin, or only its shortened preview was pasted instead of the full pk_live_... value.
Missing API key. Set BEHIO_API_KEY env varThere is no .env in the project root, or BEHIO_API_KEY in it is empty. The file must sit next to package.json and be named .env.
ERROR: Repository not found on clonessh authenticated with another key. Add -o IdentitiesOnly=yes and point -i at the deploy key.
Permission denied (publickey)Wrong path in -i, or the key was rotated in the admin and the old one no longer works.
Load key ...: invalid formatThe key file lost its trailing newline, or chmod 600 is missing. Paste the block from the admin unchanged, the heredoc handles both.
! [rejected] ... non-fast-forward on pushYou are on main but pushing to behio-draft, which is ahead. Clone with -b behio-draft, or git pull first.
Push succeeded, site unchangedYou pushed a branch with no application behind it, almost always main on a shop that is not live yet. Use the push command printed in the Lokální vývoj panel.
Push deployed, but the admin still shows the old statusExpected. The status follows admin triggered deploys only. Look at the site, or redeploy with Přepublikovat.
Status went to SelhaloThe build failed. Reproduce with npm run build locally; the deployment log is not exposed in the admin yet.

On this page