Skip to content

Troubleshooting

umutxyp edited this page Oct 17, 2026 · 2 revisions

Troubleshooting

Problems you are likely to meet with this code, what causes them, and how to fix them. The quoted messages are the ones the code prints. The FAQ is at the bottom.


Install and scripts

npm install prints EBADENGINE warnings

Cause: your Node.js is older than the pinned packages need. @sparticuz/chromium 153.0.0 needs Node ^22.17.0 || >=24.0.0, and puppeteer-core 25.11.0 needs >=22.12.0.

Fix: install Node.js 22.17+ or 24+ (see Installation), delete node_modules, and run npm install again.

npm run lint fails

Cause: the script runs next lint, and Next.js 16 removed that command. The repository has no ESLint configuration file either.

Fix: use Biome, which is already a dev dependency and configured in biome.json:

npx @biomejs/biome lint .

To lint and check formatting together:

npx @biomejs/biome check .

npm run export fails

Cause: the script runs next export, which current Next.js versions no longer provide, and the site needs a server anyway.

Fix: use npm run build and npm start, or deploy to Vercel. See Deployment.

The build fails while downloading fonts

Cause: the fonts are loaded with next/font/google (Geist and Geist Mono), which downloads them during the build.

Fix: build on a machine with internet access. To avoid the download entirely, switch the fonts in src/resources/once-ui.config.ts to next/font/local with font files you add to the project.


Pages

A page shows "404 / Page Not Found" although it exists

Cause: RouteGuard only shows pages that are listed in routes in src/resources/once-ui.config.ts with the value true (plus anything under /work and /blog when those are on). This also applies to new pages you create yourself.

Fix: add the path to routes:

const routes: RoutesConfig = {
  // ...
  "/contact": true,
};

To show it in the header too, add a button for it in src/components/Header.tsx, following the existing ones.

I set /blog to true and get a 404

Cause: the repository has no blog pages (src/app/blog/ does not exist). The setting only turns on the header button, the "Latest from the blog" block on Home and the sitemap entry.

Fix: set /blog back to false, or build the blog pages yourself.

My text shows %something.key% instead of a number

Cause: that token is not known to src/lib/live-stats.ts. Unknown tokens are left as they are.

Fix: replace the token with plain text, or add the project and key to SOURCES and FALLBACK in live-stats.ts. See Live numbers.

The log says live stats: https://codeshare.me/... unreadable, using last known values

Cause: the stats page could not be fetched (no internet during the build, a timeout, or an HTTP error).

Fix: nothing breaks: the values in FALLBACK are used. If you do not use the author's numbers, remove the tokens from your text so the site no longer depends on codeshare.me.

The GitHub page says "GitHub rate limits prevented loading repositories"

Cause: the GitHub API returned an error or nothing at all. GitHub limits how often unauthenticated requests can be made, and builds on shared machines hit that limit more easily. The message is also shown when every repository you have is pinned, or github.username has no public repositories.

Fix: check github.username in site-data.tsx, then wait. The data is cached for one hour, so the page recovers on its own once GitHub answers again.

The "Pinned work" section is missing or shows the wrong repositories

Cause: pins are read from your public GitHub profile page. If that read fails, the site falls back to github.highlight. Pinned repositories owned by an organisation are left out, because they are not in your own repository list.

Fix: pin the repositories you want on your GitHub profile, and keep github.highlight up to date as a fallback.


Images and screenshots

The log says screenshot <slug> <- <url> failed: ...

The route could not capture the project's website. During npm run dev and npm run build it then shows the first image in the project's images instead, so the page still works.

Reason in the log What it means Fix
An error about launching the browser Chromium could not start (common on Windows and macOS, where the bundled Linux build does not run) Set CHROMIUM_PATH to an installed Chrome or Chromium, or ignore it locally
HTTP 4xx / HTTP 5xx / HTTP no response The site returned an error Check link / screenshotUrl
landed on a bot check or consent page ("...") The site showed "Just a moment", "Verify you are human", a consent wall and so on Use screenshotUrl for a page without the check, or screenshot: false
A navigation timeout The page took more than 25 seconds to load Use a lighter page in screenshotUrl, or screenshot: false

A project has no cover at all

Cause: the project has no entry in images. Without one there is no cover and no live screenshot, because the screenshot needs a fallback.

Fix: add at least one image path under images in the project's front matter.

The gallery shows a broken image

Cause: gallery in site-data.tsx lists a /screenshots/<slug> for a project you deleted, or a file that is not in public/.

Fix: remove or correct that entry.

next/image complains that a hostname is not configured

Cause: you used an image from another website. next.config.mjs only allows www.google.com.

Fix: add the host to images.remotePatterns:

images: {
  remotePatterns: [
    { protocol: "https", hostname: "www.google.com", pathname: "**" },
    { protocol: "https", hostname: "images.example.com", pathname: "**" },
  ],
},

Restart npm run dev afterwards.

The share image for the Home page is missing

Cause: home.image in content.tsx is /images/og/home.jpg, and that file is not in the repository.

Fix: add an image at public/images/og/home.jpg (or change home.image to an image you have).

Generated share images show the author's avatar, or fail

Cause: /api/og/generate loads your avatar from meta.baseURL + person.avatar, and downloads the Geist font from Google Fonts on each request. If baseURL still points to the author's site, his avatar appears; if the font cannot be downloaded, the route fails with failed to load font data.

Fix: set meta.baseURL to your own deployed address, and make sure the server can reach fonts.googleapis.com.

Once UI's OgCard shows nothing

Cause: given a url, OgCard asks /api/og/fetch for the preview and loads outside images through /api/og/proxy. This repository does not have those routes (they fetched any URL they were given), so the request fails, the browser console shows Error fetching og data, and the card renders nothing.

Fix: pass the preview yourself with the ogData prop (title, description, image, url) and leave out url, so the card does not call those routes.

The build is slow or a page times out

Cause: every project screenshot is captured during the build. A slow site can take a while; the limit per page is 180 seconds (staticPageGenerationTimeout).

Fix: set screenshot: false on projects whose sites are slow or unreliable.


Password pages

The password page appears but every password is rejected

Check what the browser received:

Message Cause Fix
"Incorrect password" with HTTP 401 The password does not match PAGE_ACCESS_PASSWORD Check for typos and extra spaces in .env.local
"Incorrect password", and the server log shows PAGE_ACCESS_PASSWORD environment variable is not set The variable is missing (the API answered 500) Set it in .env.local or your host, then restart npm run dev or redeploy

I unlocked a page and later it asks again

That is expected: the authToken cookie lasts one hour.

Protecting /work did not protect the case studies

protectedRoutes matches exact paths only. Add each path you want protected, for example "/work/my-project": true.


Theme

Changing style.theme does nothing

Cause: the start-up script in src/app/layout.tsx always starts from the visitor's saved choice or, if there is none, their system setting. It does not read style.theme.

Fix: to force a starting theme, edit the resolveTheme logic in that script.

The site keeps the old theme in my browser

Cause: your last choice is saved in localStorage under data-theme.

Fix: use the toggle in the header, or clear the site's data in your browser.


FAQ

Do I need a database? No. All content lives in files: site-data.tsx, content.tsx and the .mdx project files.

Do I have to use Vercel? No. Any server with Node.js 22.17+ or 24+ can run npm run build and npm start. Vercel is simply the easiest place for the live screenshots. See Deployment.

Can I use Yarn or pnpm? The repository ships package-lock.json, so npm is what it is set up and tested with.

How do I remove the live numbers? Delete the %...% tokens from hero.subline, about.introDescription, the experience achievements and your project files, and write the numbers (or other words) yourself.

How do I add a new page? Create src/app/<name>/page.tsx, add "/<name>": true to routes, and add a header button in src/components/Header.tsx if you want one.

How do I change the colours? Change brand, accent and neutral in style in once-ui.config.ts. All allowed values are on Configuration.

Is there a blog? Not in this repository. The settings and components for one (/blog route, Posts, ShareSection, RSS) exist, but there are no blog pages or posts.

Is the password protection secure? It is a light gate, fine for a draft page. It is checked in the browser and the cookie value is a fixed string. Do not use it for private information.

Can I use this for my own portfolio? Yes. It is MIT licensed: use it, change it, publish it; keep the license notice in your copy.

Where do I ask for help or report a bug? Open an issue on GitHub. See Contributing.

Clone this wiki locally