Taking the Careers Page Out of the Code ― Decoupling Updates from Dev Requests with Hydrogen × Sanity
What this article covers
- Why a headless setup ends up routing every update through a developer
- What the headless CMS Sanity is, and why we chose it this time
- How to split a single site by who can edit what, and where
- Where the line falls between changes that need no development and changes that do
- What tripped us up running Sanity on Oxygen, Hydrogen's runtime
Updating the Careers page meant filing a request with the dev team
Our corporate site is built on Hydrogen, Shopify's headless commerce framework. The Careers page, where we list our job openings, sat on the same stack. But this one page had a problem: its content lived inside the code.
Until we reworked it in July 2026, the file that rendered the Careers page was 751 lines long, most of it hard-coded. The list of open positions, the requirements, the bullet points on compensation and benefits, even which photos appear at the top ― all of it existed as strings in the source code.
“Remove this one sentence.” “Add one more position.” These are the kinds of changes a hiring team makes. But each one meant filing a request with the dev team, who would edit the code, get it reviewed and deploy. A change that takes minutes to write came with that whole procedure attached.
When people weigh headless commerce, one concern comes up almost every time: “Won't updates become a hassle?” This is exactly the situation they mean. We decided to fix it on our own site.
Splitting responsibilities by who can edit what, and where
Our approach was to give the frequently changing content a place of its own where it can be edited. We chose Sanity, a headless CMS.
Sanity as a headless CMS

A conventional CMS bundles two jobs: storing the content, and assembling it into web pages. A headless CMS drops the second one. It concentrates on storing content in a structured way and making it available to the outside. Rendering is the job of whatever fetches it ― in our case, Hydrogen.
Because the roles are separate, the same content can go to a website and to an app alike, and a redesign of the site leaves the content untouched. This positioning is why Sanity describes itself as “The Content Operations Platform.”
Among the many headless CMSs, Sanity has a few distinctive traits.
- You design the fields yourself. Definitions such as “the Careers page has a part called Hero, with a heading, body text and a list of photos” are written in code by the developers. Rather than squeezing your information into a fixed template, you shape the template around your information
- The editing UI is yours. Sanity's editor, called Studio, exists as an app your own team manages. The order of fields, the helper text on each input ― you tune all of it yourselves
- Body text is stored as structured data. Instead of HTML it uses a format called Portable Text. As the official site puts it ― “rich text, images, code blocks, and any custom type you define” ― elements beyond text are supported once you define a type for them
Why Sanity
Against our requirements, three things settled it.
- Japanese and English can live in a single document. Because we design the fields, we could give every field a pair of inputs, one for Japanese and one for English
- There is a supported way to edit while looking at the preview. Configure Sanity's official Presentation Tool and the site appears inside the editor; you click the element you want to change on the preview, and the matching input opens. It does not work out of the box, though ― the config needs a preview URL and the logic that maps URLs to documents
- There is an official toolkit for Hydrogen. Sanity publishes a package called hydrogen-sanity that bundles data fetching and the preview plumbing. It is not strictly required for the integration, but it proved useful in solving the runtime issue described later
Staying entirely within Shopify was also an option. Shopify has Metaobjects, which hold structured data beyond products ― in fact, our site's glossary is managed with them. We didn't take that route for the Careers section not because Shopify can't do it, but because, for the editing experience we wanted this time ― dragging sections into a new order and fixing copy against a live preview ― Sanity was the shorter path within the effort we could spend on operations. With a different team or different existing assets, the same requirements could lead to a different answer.
Three places where content gets edited
One thing is worth clarifying. Every page on our site is rendered by Hydrogen and runs on Oxygen, Shopify's hosting. In that sense, the whole site sits on Shopify.
What differs is where the content on each page is stored, and who can change it. Today our site splits three ways on that point.
The important part is that we did not push everything into the CMS. Areas where publishing already worked stayed in the Shopify admin. About and Services stayed in the code, because they rarely change. Only the Careers section ― which changes often and is edited by non-engineers ― moved to the new editor. Keeping the scope narrow is what got it into production sooner. If the need arises, the same method can move other pages out later.
What we handed over wasn't the text ― it was how the page is assembled
There is a familiar failure mode: you introduce a CMS, and day-to-day work barely changes. Copy can be swapped, but “add one more section” or “put them in a different order” still goes back to the dev team.
So this time we designed the Careers page as building blocks. The hero at the top, company values, member voices, the company deck, open positions, requirements and benefits, the org chart ― each is an independent part that editors can drag into a new order in the editing UI. They can add, remove, and toggle visibility.
The caveat: what can be done without development stops at rearranging the kinds of sections that already exist. “A kind of section that doesn't exist yet” or “a different layout inside a section” means touching both the type definitions and the rendering code, so that is dev work. Where to draw this line is the real design question in this kind of project.
The point is that the information about which section goes where lives on the CMS side. The site simply renders the parts in the order it receives them.
With the move to Sanity, the Careers page file went from 751 lines to 64. But that is not “the code shrank to a twelfth.” The logic that assembles the screen moved into a new file (303 lines at the time). Across the whole change, 732 lines were added and 850 removed across 15 files ― the total barely moved. Whether maintenance got lighter is a separate question.
What changed is not the amount of code but where things are written. The job postings left the code and moved into the editor.
We also designed how Japanese and English are handled. Our site is published in both languages, and if you build two pages per language, one tends to get updated while the other doesn't, and the two drift apart. So every field got two inputs, Japanese and English. Open one document and you see both, so drift is easy to spot. On top of that, we implemented a fallback that shows the Japanese text when the English field is empty. This is not Sanity's default behaviour; it is logic written on the site side. It means the English page never goes blank while a translation is still pending.
Swapping the contents without changing how it looks
A common worry when moving an existing page into a CMS is that the design will shift. We made “the look does not change” a precondition and reused the existing styles and components as they were. The only new code is the piece that hands the data received from Sanity to those existing parts.
With that precondition in place, the worry that “the design might change” drops out of the discussion. What's left to decide is a single question: how the operation should change.
Where Oxygen tripped us up
One implementation snag, for anyone considering the same setup.
Oxygen, Hydrogen's hosting, does not run on ordinary Node.js but on a Workers-style runtime (workerd). It is close to a browser environment but not identical ― a distinctive runtime of its own. Libraries written for Node.js don't always work there unchanged.
In our first test we concluded that Sanity's data-fetching library didn't run in this environment, and shelved it. The real issue turned out to be that a dependency used internally wasn't being bundled correctly when imported the straightforward way. The build configuration included in hydrogen-sanity resolved it; we built, ran it in an Oxygen-equivalent environment, and confirmed it worked.
From the outside, “it doesn't work” and “we came in through the wrong door” look the same. When there is an official toolkit, try it first. It looked like a detour and turned out to be the shortcut.
Operating it after launch
On July 12, 2026, we shipped the change that serves the Careers page and the interview articles from Sanity to production. The preview-editing setup went live the same day.
From the editor's point of view, the screen works like this:
- Edit while looking at the preview. Click the element you want to change and the matching input opens
- Work in progress is saved automatically, but nothing appears on the site until you press Publish
- Edit history is kept, so you can restore an earlier state within your plan's history retention period (Sanity trims older revisions once they pass the period defined for your plan)
- After publishing, allow about two minutes for the site to catch up. This is not a Sanity limitation; it comes from the cache lifetime configured on the site side
What we made a point of is being explicit about what editors can change themselves and what they can't. The org chart image, for example, is built into the site and can't be changed from the editor. Sharing that boundary up front removes the “I should be able to change this ― where is it?” moments.
Where this setup fits
This setup suits situations like these:
- E-commerce runs on Shopify, but updating pages such as careers, case studies or news has turned into a dev request
- There are pages where freshness directly affects results (a careers page is the textbook example)
- You operate in more than one language, such as Japanese and English
- You don't want to change the design, but you do want to change how it is operated
Headless commerce gets described as hard to update. What actually makes it hard is not designing who can update what. Break the page into parts and hand editors those parts along with their ordering, and part of the operation comes back into your own hands while staying headless. How much to hand over, and how much to keep as development work ― that line is the design. We confirmed it on our own page.
For headless commerce builds on Hydrogen, and for designs that pair it with a CMS as we did here, feel free to get in touch.