.─[ pulse ]─────────────.
┌─────────────────────┐
                     
                     
                     
                     
                     
                     
                     
                     
                     
                     
                     
                     
                     
└─────────────────────┘
'─[ asciiart.eu ]───────'
I - BSOYD Autism NGO Website
~ Erdem Hanay
──[ VOL.1 :: BSOYD ]─────────────────────────────────────────────────────────//─
──
    :..........................................................................:

[>] Project Link: https://bendensonra.org/

──[ 0x00 waiter ]───────────────────────────────────────────────────────────//──
─

It was a hot summer day.
I needed money.
A local Autism NGO was just getting started.
They were throwing an initial shareholder event
at a local Hilton Hotel.
The audience: shareholders, NGO members,
and families of children on the autism spectrum.
There was a presentation and all that jazz.
The attendees were going to spend at least 4 hours there.
The hotel didnt provided any waitstaff for the event,
so I went there as a waiter.

Quickly, I became responsible for
the whole food and venue situation.
The people who attended the event
quickly noticed how much effort I put into my work.
It was like waiting tables was my passion.
I did this to show everyone my work ethic,
how you do one thing is how you do everything.
I managed to socialize with everyone there.
While we were packing up the venue,
the NGO president told me she was grateful I was there.
I started talking to her, mentioning that
I was interested in web development
and could build them a website for a reasonable price.
The NGO was young, so they didn't have a website yet,
but desperately needed one.
She agreed, and I started the work that night.
She sent over the legal registration documents.

──[ 0x01 plan ]─────────────────────────────────────────────────────────────//──
─

First thing I did was create an "architecture.md" file
and write down every plan in my mind.
I researched and refined it through 5 iterations
before touching a single line of code.
Then I drafted all the required content,
learning how to write website terms,
conditions, and legal policies.

──[ 0x02 cms ]──────────────────────────────────────────────────────────────//──
─

Then I noticed something:
the website needed a CMS
because they would post updates pretty regularly,
and changing source code every time wasnt viable.
So I started researching Headless CMS options.

My thought process here was:
a CMS interacts with a multitude of abstraction layers
from security and caching to cookies and routing.
It also needs authentication and a configured database.
If I built the database and auth from scratch,
it would take me forever to do,
because aside from tutorials and some homelabbing,
I had never dealt with production databases.
I also didnt trust myself to handle authentication safely yet.
If I accidentally made an API route public
or messed up the cookie configuration
for session authorization levels,
the whole CMS could be taken over.

I researched the most valid options
and chose Sanity Headless CMS.
I read the docs and learned the
ins and outs of the system.
Writing the database schema was
way funnier than I imagined.
I built a prototype that worked on
localhost with all required layers.
Here, I learned the CORS protocol as well.

──[ 0x03 seo ]──────────────────────────────────────────────────────────────//──
─

I thought I could handle SEO
simply by utilizing meta tags,
but I was missing a fundamental point:
the framework I used was pure Vue.js (Client-Side Rendering).
This meant meta tags would only be available
once the website was rendered
on the client side unless placed in `index.html`.
Naturally, I made the mistake of putting them into `App.vue`,
so Google didn't index those tags at all.

Anyway, the database schemas and functionality worked fully.
That wasn't really a surprise since it was a managed Headless CMS,
I just read the documentation and adapted it to our needs.
Still, it felt great that it worked.
The admin domain was completely isolated from the website routes
it wasn't a monorepo; the backend and frontend were fully separated.

Also, I hadn't configured any CSP in `vercel.json` yet,
so our HTTPS security score was 40/100.
To be fair, a site reading from a
Headless CMS didnt strictly need nonces,
as there were no user input fields
and the database was read only from the client side,
meaning zero danger of XSS attacks.

──[ 0x04 iterations ]───────────────────────────────────────────────────────//──
─

I remember discovering lazy loading in the first iteration
and being very excited about it.
Now the website didn't download everything in its entirety upfront,
it only fetched assets as the client scrolled into view.

In the second iteration,
I noticed the issue with SEO
and moved the meta tags to `index.html`.
That didnt magically fix SEO it was just slightly better.
Google still didn't index the actual dynamic content inside the website.

In the third iteration,
I added a very oppressive CSP in `vercel.json`.
I scored a 130/100 on the Mozilla HTTPS security test.
I thought that was a massive success, but it wasn't.
Development in later iterations
suffered greatly from this redundant security measure.
I had to reconfigure everything constantly and kept hitting CSP errors.
Unneeded, oppressive security just shows how inexperienced a developer is.
Sometimes a site with an 80/100 security score is better than 140/100,
because you have to balance utility and developer velocity with security.
In rare instances, an incorrectly configured CSP
can even introduce weird edge-case issues.
Of course, I didnt know all of this at the time,
so I was super proud of myself.
Oh, how ignorant I was then.

Then the fourth iteration came along,
where I integrated `vue-i18n` for internationalization.
We translated the website into 8 languages.
By that time, I had built a team of 12 student translators,
and we had actually just published a book together
(you can find that book's case study elsewhere in this volume).
I entered all the locale data by hand because I didn't know any better.
I also added a credit segment for my friends who worked on the translations
many of whom landed internships thanks to this real world experience.

In the fifth iteration,
I fixed a very obvious oversight: our website had no 404 handler.
I built a 404 page utilizing Vue Router,
but then noticed it wasn't showing up on Vercel.
So I started debugging which, at that stage of my career,
just meant trying random things without knowing what was actually wrong.

Eventually, I figured it out,
whenever I clicked the browsers back button or refreshed a route,
Vercel threw a hard routing error.
I hadn't configured "vercel.json" correctly to work with a Vue SPA.
Vue renders routed pages in a "".vue"" views system,
but Vercel was searching the server
for physical "".html"" files at those routes.
It couldn't find them, so it failed.
I added singlepage application rewrite rules to `vercel.json`,
redirecting all incoming routes back to
"index.html", which fixed it completely.

In the sixth iteration,
I added Vercel Edge Middleware for geolocation.
Since we had multiple languages,
the server would read the user's location
and guess their primary language.
It was easy to do by following the docs.
Later, I optimized `LangChanger.vue`
so that the browser's explicit language header
took precedence over the geolocation estimate from the middleware.
It just made more sense for UX.

In the seventh iteration,
the client requested analytics.
I chose Google Analytics because it has
the best ecosystem for non-technical users,
allowing my client to check traffic data
safely without breaking anything.
I added GA directly into "index.html" at first.

In the eighth iteration,
I learned about Service Workers.
I implemented a client side caching system
and placed Google Analytics behind an explicit cookie consent choice.

In the ninth iteration,
after getting comfortable with Service Workers,
I learned how to convert the app into a Progressive Web App (PWA).
Looking back retrospectively, making it a PWA was unnecessary.
But because this was my first contract,
I tried to implement as many concepts as possible just to learn.

In the tenth iteration,
I overhauled the entire UI/UX system of the website.

──[ 0x05 access ]───────────────────────────────────────────────────────────//──
─

In the eleventh iteration,
I noticed something critical.
Because the client wanted a lot of interactive UI/UX elements
(all NGO sites seem to feature a diabolical amount of UI fluff),
our website was very visually stimulating.
This might seem great at first glance,
it made the NGO look active
but this was an *Autism* NGO.
I have a relative on the spectrum, and I knew firsthand
how overwhelming high visual stimulation can be.

I started researching web accessibility
and read the W3C WCAG 2.1 guidelines.
I made the necessary accessibility adjustments
and engineered an entirely separate
"Low Stimulation Mode" for the UI.
I added an initial landing modal asking
first time visitors which version they preferred.
While the user was making their choice,
I utilized that idle time to
preload website content in the background,
prioritizing the most frequently visited routes.
Because all content was fetched from the Headless CMS API,
a single preloading cycle populated
both versions of the UI without double fetching.

In the tweleth iteration,
I made small UI tweaks, and the initial build was done.
I considered migrating the codebase to SSR or SSG,
but that would have taken considerable time,
and since I was taking on a new client contract, it was unnecessary.

──[ 0x06 production ]───────────────────────────────────────────────────────//──
─

Then an unexpected production bug happened this past April.
In April 2026, Vercel suffered a security incident
where an employee's OpenAI API key got leaked,
leading Vercel to harden security
permissions across organization accounts.
The Vercel account I initially published the project under
and the account I used for updates were different,
and I suddenly lost deployment rights from my primary account.

There was a simple way to transfer
project permissions through the dashboard settings,
but I assumed managing everything
from a single fresh deployment would be cleaner,
so I decided to migrate.
I took down the old deployment
and redeployed the codebase under my main account,
re-configuring the API keys, CORS origins, and domain mappings.

However, I made a major mistake configuring the custom domain:
I linked the domain inside Vercel,
but failed to update the DNS records properly at the registrar.
The site was accessible via direct URL,
but disappeared from search engine indexing
and broke SSL routing. It was a big oversight,
and as soon as I caught it, I fixed the Arecords.
The way I handled that deployment was abysmal,
but in the end, I learned a massive lesson
in zero ego infrastructure management
and delivered a platform that runs cleanly in production.

    :..........................................................................:
──[ EOF :: vol.1 / BSOYD ]───────────────────────────────────────────────────//─
──