Repository navigation
Pages and Features
A tour of everything the site does: each page, the live parts, search and sharing, and the API routes. Settings mentioned here are described in full on Configuration.

- A large headline (
hero.headline) and a subline under it (hero.subline). The subline can contain live numbers and**bold**text. - An optional featured badge above the headline (
home.featured.display, off by default). - A button to the About page, with your avatar and the About page title.
- A newsletter block at the bottom when
newsletter.displayistrue(off by default). - If
/blogis switched on inroutes, a "Latest from the blog" section that reads posts fromsrc/app/blog/posts/. The repository does not include blog posts or blog pages.
From top to bottom:
- Avatar (if
about.avatar.display), your name and role. - Your time zone next to a globe icon (
person.timezone). - Language tags (
person.languages). - Social links as buttons. On small screens they become icon-only buttons.
- A "Schedule a call" pill (if
about.calendar.display). -
Intro (
about.intro), Work Experience, Studies and Technical focus. Each section can be hidden incontent.tsx.
Intro text and experience achievements support live numbers and **bold**.
One card per .mdx file in src/app/work/projects/. Each card shows:
- the cover image (a live screenshot when available),
- the title and summary,
- Read case study (only when the file has text after its front matter),
-
View project (only when the file has a
link).
Cards are sorted by the order field, lowest first. Projects without order come last, newest publishedAt first. See Adding Projects.
The slug is the file name without .mdx. The page shows:
- a "Projects" link back to
/work, the publish date and the title, - team avatars and names (each name links to the member's
linkedInURL), - the cover image (16:10),
- the MDX content, with live numbers filled in,
- a Visit <title> button when
linkis set, - a Related projects list: the other projects in
/workorder, except the first of them (the page asks forrange={[2]}).
All case study pages are generated at build time.
A masonry grid of the images listed in siteData.gallery: two columns on wide screens, one column on phones. By default it shows the live screenshots of all eight example projects.
-
Pinned work: the repositories pinned on your GitHub profile, in the same order. The site reads them from your public profile page, because the GitHub REST API does not expose pins. If that fails, it uses
github.highlightinstead. Pinned repositories owned by an organisation are left out, because they are not in your own repository list. - Other repositories: all your other public repositories (up to 100), most stars first.
- Each card shows the name, description (or "This project ships without a description yet."), language with GitHub's colour dot, stars, forks and the last update date.
- Data is cached for one hour.
If GitHub returns nothing, the page shows: "GitHub rate limits prevented loading repositories. Try again in a few minutes."
Any unknown page, and any page switched off in routes, shows "404 – Page Not Found".
-
Header: a floating bar with a button for each enabled page and, if
display.themeSwitcheris on, a light/dark toggle. On screens 768 px wide or less it sits at the bottom of the screen and the buttons show icons only (Home keeps its label). -
Footer:
© <year> umutxypand an icon for each social link. -
Light and dark mode: on the first visit the site follows the visitor's system setting. The toggle switches between light and dark and the choice is remembered in the browser (
localStorage, keydata-theme). Thestyle.themevalue in the config is not read by the start-up script. -
Look: colours, borders, surfaces and scaling come from
style; the background (dots by default) comes fromeffects.
Text can contain tokens like %beatra.servers% or %mcstat.players%. When a page is built, src/lib/live-stats.ts replaces them with current numbers.
Where tokens work: hero.subline, about.introDescription, every experience achievement, and a project's summary and MDX content.
Where the numbers come from: stat tiles on codeshare.me, the author's studio site. Each tile is HTML of the form <dd>value</dd><dt>label</dt>. The code knows these pages and labels:
| Token prefix | Page read | Keys |
|---|---|---|
studio |
/ |
products, servers, users, players
|
beatra |
/projects/beatra |
servers, users, playing
|
sylon |
/projects/sylon |
servers, users, uptime
|
mcstat |
/projects/mcstat |
servers, players, skins, capes
|
justdiscord |
/projects/justdiscord |
servers, bots, emojis, visitors
|
justanime |
/projects/justanime |
titles, characters, schedule
|
How it behaves:
- Numbers are read at build time and refreshed every 7 days.
- If a page cannot be read, the last known values stored in the code (
FALLBACK) are used, and the log showslive stats: https://codeshare.me/... unreadable, using last known values: .... - An unknown token (for example a typo) is left in the text as it is.
For your own portfolio you have two choices:
- Write plain numbers. Remove the tokens from your text. Nothing else is needed.
-
Use your own source. In
src/lib/live-stats.ts, changeSOURCEto your site, describe your pages and labels inSOURCES, and set starting values inFALLBACK. Your pages must contain the same<dd>value</dd><dt>label</dt>markup.
Each project's cover can be a real screenshot of its website, served from /screenshots/<slug>.
When a project gets one: its front matter does not say screenshot: false, it has a link (or screenshotUrl), and it has at least one entry in images. The first image is the fallback.
How a capture works (src/app/screenshots/[slug]/route.ts):
- Chromium opens the page at 1600 × 1000 (scale 1.25, so the image is 2000 × 1250), in dark mode with reduced motion.
- It waits up to 25 seconds for the page to load, then up to 8 seconds for the network to go quiet.
- It hides cookie and consent banners, waits 2.5 seconds for late popups, presses Escape, then hides dialogs, full-screen overlays and anything pinned to the lower half of the screen.
- It refuses pages that look like a bot check or a consent wall (for example "Just a moment", "Verify you are human").
- It saves a JPEG at quality 80.
When it runs: every screenshot is taken during the build and refreshed in the background once a week.
When it fails:
- During
next buildornext dev, the route serves the project's first image frompublic/instead. - During a weekly refresh, the last good screenshot is kept and the capture is retried later.
- Either way the log shows
screenshot <slug> <- <url> failed: <reason>.
The covers are used on /work, on case study pages and in the gallery.
- Add the page to
protectedRoutesinonce-ui.config.ts, for example"/about": true. - Set
PAGE_ACCESS_PASSWORDin.env.localor in your host's settings.
Visitors then see "This page is password protected" with a password field. The password is sent to POST /api/authenticate; if it is right, the server sets an authToken cookie for one hour and the page appears. A wrong password shows "Incorrect password".
Warning: This is a light gate for things like a draft page. It is checked in the browser by
RouteGuard, and the cookie value is the fixed textauthenticated. Do not use it to hide anything secret.
| Feature | Where |
|---|---|
| Page title, description and Open Graph tags | Home, About, Work, case studies and Gallery, through Once UI's Meta.generate. /github sets its own title and description. |
| Schema.org data | Every page except the 404 page, through Once UI's Schema (webPage, or blogPosting for case studies) |
| Generated Open Graph images | /api/og/generate?title=... |
| Sitemap |
/sitemap.xml: enabled routes, every case study, and blog posts if any |
| Robots |
/robots.txt: allows all crawlers and links the sitemap |
| RSS feed |
/api/rss: reads src/app/blog/posts/, which does not exist in this repository, so the feed has no items |
Open Graph images are 1280 × 720 PNGs with a dark background, the page title, your avatar, your name and your role. The Geist font is downloaded from Google Fonts each time an image is made, and the avatar is loaded from baseURL, so set meta.baseURL to your own domain.
| Route | Method | What it does |
|---|---|---|
/api/authenticate |
POST | Body {"password": "..."}. Returns 200 {"success": true} and sets the authToken cookie, 401 {"message": "Incorrect password"}, or 500 if PAGE_ACCESS_PASSWORD is not set. |
/api/check-auth |
GET |
200 {"authenticated": true} if the cookie is present, otherwise 401 {"authenticated": false}. |
/api/og/generate |
GET |
?title= → a 1280 × 720 PNG. Title defaults to Portfolio. |
/api/rss |
GET | RSS 2.0 feed (see above). Every value is XML-escaped, and the post summary is escaped text rather than a CDATA block, so &, < or quotes in a title, summary or tag do not break the feed. |
/screenshots/<slug> |
GET | The project's screenshot as JPEG (see above). |
Note: There is no
/api/og/fetchor/api/og/proxy. Those routes came with the Once UI template and fetched whatever URL they were given; nothing on the site used them, so they were removed. Once UI'sOgCardlink preview loads its data from those two routes, so it does not work here unless you give it the preview yourself (see Troubleshooting).
next.config.mjs permanently redirects /work/code-share-marketplace to /work/codeshare-technology. It exists for an old link of the author's and is safe to remove in your copy.
Personal Website by Umut Bayraktar · MIT License · Codeshare
Start
Reference
Go live
Community