Work / Front-end / Djehuty Project · The site in React
Thirteen years running this site, and now rebuilt in React
Project 15 of 28 in the archive 06 of 08 in Front-end development See the whole discipline ↗
This one is read inside the frame, and only inside the frame
The content is not mine: it belongs to an archaeological mission that has been digging and publishing for twenty years. Showing my layout work here is one thing; leaving a navigable copy of their site loose on the internet is another, and it is not mine to do. So this rebuild does not open outside this page: reach it through a direct link and it will not start. In exchange, the frame below changes size.
Desktop or phone, without leaving this page
Thirteen years of work that are no longer online
The Djehuty Project website is the public archive of an excavation that began in 2002. Inside it are the day-by-day season diary, a card for every member of the team, the annual summaries, the tomb guide, the geographic, historical and cultural context, the publications and the press. None of it can be rewritten or summarised: it is scientific material and it is signed.
That site was mine to run from 2006 to 2019: the layout, the stylesheets, the JavaScript, and the loading of every season as it came out of the ground. The templating of the PHP was mine too, four hands with the person handling the server side: we wrote the templates between us, and out of that came 1,356 files and 121,420 lines in which template, query and text end up sharing the same file, with jQuery 1.11 and Magnific Popup on top.
That was normal in 2006 and stayed normal for thirteen years. The price shows up now: my work doesn’t live anywhere, it is scattered and repeated across those 1,356 files, and there is no way to show it without standing up a PHP server.
And there is a blunter reason. Since 2019 someone else has run the site and has changed its design: what is online today is no longer what I made. So the brief I set myself has two halves. One, put that version back up with today's tools, so that it exists somewhere and can be shown. Two, do it in React, which is the part of me I want to demonstrate now. If anyone can tell the difference from the original at the end, it has been done badly.
Pages of content
Pulled out of the PHP into JSON, comma for commaDays of diary
Eighteen seasons, entry by entryTeam cards
Eighteen years of people on the digReact routes
One for every.php?year=…&option=… of the originalThe rule everything else follows
The design does not get touched — least of all when this is the only place it survives. The stylesheets are the ones I wrote across those thirteen years — 867 lines of common.css and view_gallerie.css — linked unmodified, and the typefaces are the same ones. It would have been very easy to use the trip to tidy up what I would do differently today, and that is exactly why I haven’t: this is not a redesign, it is an archive. And as an archive it is only worth something if there is no cheating.
Get the text out first, then put it back up
The rebuild is two jobs in a row, and the order matters: while the content is still inside the PHP there is nothing to lay out. A Node script walks the 1,356 files, strips the logic, rewrites image and link paths and leaves 1,269 fragments of clean HTML in JSON. From there, React only has to paint them.
The result is 1,260 lines of components against the 121,420 it started from. That is not magic: 98 % of the original was the same <header> repeated 1,356 times.
01 · One component for the inherited HTML
The extracted content is still 2019 markup, and that markup expected jQuery to wire things onto it. Html.jsx — 109 lines — paints it and hands back exactly what it lost: internal links resolve through the router without a reload, galleries open full screen, the video thumbnail is replaced by the <video>, and the vertical menu unfolds on a phone.
It is the piece that saves rewriting 1,269 pages by hand. Touch it once and the whole site is fixed.
src/components · Html.jsx109 lines · 4 behaviours
02 · The gallery, without jQuery and on the same stylesheet
The original image viewer was Magnific Popup: 48 KB of plugin plus the 96 KB of jQuery underneath it. 72 lines replace it, producing the same markup — the same mfp- classes — which is why view_gallerie.css styles it without a single change.
It also does something the original never did: it closes on Esc and steps through on the arrow keys.
src/components · Lightbox.jsx144 KB of library → 72 lines
03 · The old addresses still mean the same thing
A scientific archive gets cited, and what gets cited are its URLs. So the route map was not invented from scratch: every .php with its parameters has an exact equivalent, and a translator converts internal links on the fly as the content is extracted.
diario_de_excavacion_dia.php?year=2018&dia=02-24 is now /diario/2018/02-24, and the defaults — 2018 seasons, 2019 diary and team, plano, egipto — are the ones the PHP had.
scripts · php-utils.mjs38 routes · defaults inherited
04 · Genuinely responsive, because the original already was
The 2019 site was laid out for phones, and laid out well. Because the CSS is untouched, that layout is still alive: the menu becomes a burger, the year bar reflows into four columns and the galleries drop to a single column.
That is the part of the exercise I most want to show, and the reason the frame below has a size control: no screenshot can prove that something is responsive. Either you narrow it yourself, or you are taking my word for it.
common/css · common.css867 original lines, untouched
And it runs on a double click, with no server
A <script type="module"> and a fetch() are both fetched under CORS rules, and a file opened straight off disk is given the null origin, so the browser blocks both. With Vite's usual output, the frame comes up blank. So the bundle is compiled as a classic script and the 1,269 fragments are served as .js files calling a global function, rather than as JSON that has to be requested. Over HTTP it behaves identically; the difference is that this way it also works locally.
Four gigabytes do not fit in a portfolio
The original site's media weighs 4 GB: 17,231 photographs, twelve videos in three formats each and 250 MB of PDFs. Bringing all of that here would be absurd, and leaving it out would turn the rebuild into an empty shell. The decision was made with numbers, not by eye.
And there is one thing I deliberately did not fix: about fifty images still fail to load. They were broken on the original server — the file is not there — and that is how they have been left. Repairing them would have meant inventing content that never existed.
Less image weight
17,231 JPGs to WebP: 1,653 MB down to 357 MBOf video dropped
The spare .ogv and .webm tracks, redundant todayOf PDFs left out
Their links say so instead of returning a 404Of JavaScript over the wire
The whole site, with no third-party libraryA broken link gets announced, not hidden
The PDFs that do not travel have not been cut out of the text: their links are marked, and clicking one brings up a note saying they are not part of the demo. A link that leads nowhere is worse than a link that says where it does not lead, and a visitor deserves to know which of the two they are looking at.
The site, running
The whole site is below: drop into the diary for any of the eighteen years, open a day, enlarge a photograph from the gallery, switch a season into another language or walk through the tomb guide. Everything on screen is real Djehuty Project content, served from React.
What is actually worth trying is the control at the top right: switch the frame to phone size and watch it answer. Nothing is being scaled; it is simply being handed a different width, and the site rearranges itself.
The texts, photographs and videos belong to the Djehuty Project, the Spanish-Egyptian archaeological mission directed by José Manuel Galán at the CSIC. What is mine is the front-end — the site from 2006 to 2019 and this 2026 rebuild — and the share of the ceramic material I worked on as one of the team. This is not the project’s website: the real one has been run by someone else since 2019 and carries a different design today. This is my version, rebuilt so it can be shown, and that is why it does not open outside this page.
1,269 pages · 17,230 images · 224 KB of JavaScript · the frame is the only door
Where it comes from: thirteen years and a dig
I did not come to this website from the outside. The Djehuty Project belongs to the CSIC, so the thirteen years I ran the site were years working for the project and therefore for the Spanish National Research Council. I was part of the Djehuty Team as a specialist in Egyptian ceramics and seven of those years I was contracted as a researcher. I am no longer part of the Team. I was on site, washing, drawing and classifying material, and that is where the ceramics reports I signed came from. The annual season dossiers come from the same place. Both are graphic and editorial pieces, and sit in the archive under that discipline.
That is why the site was mine for thirteen years rather than a one-off commission: the person updating it every February was someone coming back from the season, and on the payroll the rest of the year. I know what a context is, why the diary is ordered by working day rather than by topic, and which photograph of a sherd cannot be cropped. When deciding what to keep and what to drop, that counts for more than any technical criterion.
Going back over your own work is an uncomfortable and very useful exercise. The real lesson is how much of those thirteen years was building a site and how much was wrestling with the scaffolding. Take the scaffolding away and 1,260 lines of components are left. The rest was repetition.
And that is why it is built in React rather than anything else. This page has to answer two questions at once: what I did for thirteen years — which can no longer be seen online, because the site has carried a different design since 2019 — and what I can do now. A screenshot would answer the first and not the second. A showcase mock-up would answer the second and not the first. Rebuilding the whole thing, with its real content and its design intact, answers both, and that is the entire reason it exists.
Next in Front-end development
My little baby