Designer. Engineer. Writer.20+ years at the intersection of design & code on the web.
The RSS's url is : https://blog.jim-nielsen.com/feed.xml
2024-11-21 03:00:00
When my site analytics reported a large number of inbound traffic from Hacker News clones, I got curious and started clicking links.[1]
I like to visit links. I am connoisseur of it. I love the feeling of landing on something you didn’t expect — which is precisely what happened.
I landed on a site that had one of those Cloudflare-esque “prove you're human” captchas. That didn’t seem particularly abnormal. Lots of website owners these days use them for protection against malicious activities like DDoS attacks.
Anyhow, the page had a little graphic that said: “Press ‘Allow' to prove you are not a robot.”
I sat there for a moment looking for a button, but couldn’t find one. “Where’s the “Allow” button?” I thought.
A few seconds later, Safari’s native permission dialog popped up asking for permission to send me notifications!
I immediately thought, “Ah, hell no!” and ran away from that website. That’s sneaky, leveraging tools site owners use to protect themselves — and therefore normalize for their users — as a weapon.
I hate this crap.
But one of the beautiful things about browser security is that a lot of people work really hard to make visiting any website in the world safe. Granted there are caveats to this statement, but it’s cool you can mostly sleep at night doing a GET to any domain. (Whereas, for example, it is very much not safe to install any package in the world from npm.) That’s great news for link hoppers like me.
THANK YOU browser makers!
Reply via: Email :: Mastodon :: Twitter
Tagged in: #grateful
2024-11-19 03:00:00
I think it’s endearing when people name their blog.
I’m not talking about branding, like people do with professional blogs or newsletters.
I’m talking about personal blogs that people name out of care and idiosyncrasy.
It’s endearing, because you brand things you own, you name things you cherish.
We didn’t brand our family cat. And we don’t call him “The Nielsen’s cat” (though that’s probably what our neighbors call him). We named him. We call him “Fluffy”.
Don’t get me wrong, I like how personal it is when a personal blog is just someone’s name (that’s what mine is).
But I also love when folks add a little name or subtitle to communicate their personal feelings about their blog, e.g. “Little nothings: the blog of so-and-so”.
Here’s a few examples out in the wild of people I follow:
My sister had a blog for a long time — though sadly not anymore [insert comment here from old man yelling at cloud about the demise of blogging in the wider public].
I can’t remember the name of her blog, but the subtitle was “tasting life twice; in the moment and in retrospection” which was a nod to Anaïs Nin. I think about that quote probably once a year — I love stuff like that!
Yeah, I know, I’m one to talk. My blog is titled “Jim Nielsen’s Blog” which, hey, at least it’s clear. Maybe I’d name it if I could land on a name I like, but I’m a fickle namer so don’t hold your breath. Perhaps I could start with a subtitle first, something like:
Oooof. Maybe I better leave this art to others.
You have a blog you follow whose name you love? Let me know — or even better, blog about it!
2024-11-16 03:00:00
Why do we write?
We write, in part, because our own reading was given as a gift to us and we want to extend that same magic we received to others. Here’s Mandy Brown (and my notes) in a recent article:
The more compelling and interesting reason that most writers seek out readers is, I think, less utilitarian: we receive our writing as a gift, and so it must be given in turn. We write because something needs to be expressed through us, and only by giving the writing to a reader is that need fulfilled
You write because something needs to be expressed through you, which is something nobody else in the world can do.
(Contrast this with writing that is expressed through an LLM that everyone else in the world has access to.)
By giving our writing to a reader its is purpose fulfilled.
In other words, reading and writing has traditionally been an act that takes place in the context of people. Its purpose is fulfilled through humans. AI bots could read and write to each other all day long, and what is being “fulfilled” in that scenario?
Reading and writing is for expression and connection between humans. Its purpose is fulfilled in that context. Anything other than this and it is purposeless; that is, done in a way that violates the reason for its existence in the first place.
Does that make sense? I’m trying to make sense of it myself. Maybe there’s something here — maybe not. But Mandy’s piece got me thinking.
Reading and writing is a human-centric exercise because it deals with the interpretation, exchange, and expression of consciousness which is an attribute that machines do not possess — “yet” some will say, and to that I say “lol”.
2024-11-14 03:00:00
Jan Miksovsky has an absolutely tremendous article about how he cobbled together some disparate pieces of hardware and software in order to help improve the quality of life of his mother who has amnesia.
Everything about this article illustrates what got me into making websites.
Everything about this article is what fuels my curiosity and interest in continuing to make boring little websites.
But first, a quick overview of Jan’s story. First, the problem:
the side-effects of a long surgery left my mom with permanent anterograde amnesia…[she] still lives on her own in an apartment. Because she cannot remember things, she goes through each day in a state of low-grade anxiety about where her grown children are and whether they are all right.
To help alleviate this, he dreamed up a solution:
I thought some sort of unobtrusive, always-on device installed in her apartment might be able to show her notes written by my siblings and me.
But technological solutions are famously fickle and rarely easy. How do you introduce a new device into someone’s life when you can’t teach them how to use it because their mind is incapable of remembering?
Not easy stuff. But Jan’s imposed set of constraints on any solution are a great start. The solution has to be:
resilient to network failures
not enshittified with a subscription service or proprietary App Store
He gives insights into the technical details:
Since it’s essentially impossible to debug anything that happens on the device, I made as much use of vanilla HTML and CSS as possible.
Boring is good! Even the “backend” where the family posts notes sounds like just an absolutely lovely little website:
A small web app manifest lets us save the Compose page to a phone’s home screen as an icon for quick access.
The whole site is tiny, entails no build process, and with the exception of the service (below) is just static files.
Jan’s retrospective is wonderful from the human side:
Looking back, the display is essentially the only intervention of any kind we’ve tried that’s actually been successful at improving her quality of life (and ours). One reason it’s worked so well is that it didn’t require her to learn anything new. Without the ability to remember new things, it’s virtually impossible for her to learn a new skill or to form new habits.
And the technical retrospective is wonderful as well:
For my part, keeping the software as simple as possible and sticking to vanilla web technologies surely helped avoid bugs.
It reminds me of the early years of the web, when nobody quite knew what was possible with all this web stuff. If you knew enough about how to patch things together on this big open standard, you could do some pretty magical things for people.
Not magical in the sense of “Hey, I think I uncovered something that I can generalize into a product and then provide as a service to the entire world” — though there was plenty of that coming out of the early days of the web.
But magical more like the way a great cook would improvise a meal for a small group of hungry people based on their needs and what was available in the pantry at the moment.
That magic of using your digital fluency to scrappily cobble together some disparate technologies in service of helping solve the unique problem of an individual loved one or friend. No scale. No monetization. No buzzwords. No grand upside potentiality.
Just building cool shit for people you love on the ethos of an open platform.
2024-11-12 03:00:00
When trying to define the difference between a link (<a>
) and a button (<button>
), a general rule of thumb is: links are for navigation, buttons are not.
That can take you pretty far. However, like most things, there’s nuance and that mental model can fall apart under certain scenarios.
Why? Because buttons can be for navigation too.
Where? Buttons in forms trigger navigations by default (without JS).
Maybe I’m showing my naivety when I say this, but it took me a while to fully grok this idea. But doing so helped me change how I think about the basic grain of building for the web.
When it comes to browser APIs, I love to ask myself: How does this thing work, at its most basic level, without JavaScript?
And a <button type=submit>
inside a <form>
is, by default, a navigation.
For example, if you click “GO” here:
<form action="https://google.com">
<button type="submit">GO</button>
</form>
The browser will navigate you to the same page as if you click “GO” here:
<a href="https://google.com">GO</a>
Both of those are what I would call “navigations”. Without JS, they trigger a round-trip request to the server for a new document and navigate the user to this new location.
To reiterate: a button inside a form, like a link, triggers a round-trip request to the server for a new document — a navigation.
So links aren’t the only mechanism for navigations, buttons are too! Or, perhaps more accurately, forms are a mechanism for navigations and buttons inside of them are navigation triggers.
As another illustration, imaging making a multiple-choice quiz. Each question is its own HTML page. You can mark that up in two different ways.
Option 1: a form + a button.
<form action='/questions/1/'>
<label><input type=radio name=answer value=a /> A</label>
<label><input type=radio name=answer value=b /> B</label>
<label><input type=radio name=answer value=c /> C</label>
<label><input type=radio name=answer value=d /> D</label>
<button type=submit>Submit</button>
</form>
Given the attributes of this form, when the user clicks the “Submit” button, the browser will navigate them to a new page such as:
/questions/1/?answer=a
You can achieve this exact same functionality with links:
<ul>
<li><a href="/questions/1?answer=a">A</a></li>
<li><a href="/questions/1?answer=b">B</a></li>
<li><a href="/questions/1?answer=c">C</a></li>
<li><a href="/questions/1?answer=d">D</a></li>
</ul>
In both cases, a “navigation” happens by default.
I write this because understanding form submissions (triggered by buttons) as navigations became an empowering idea for me in building for the web.
Maybe it will for you too.
Reply via: Email :: Mastodon :: Twitter
Tagged in: #webPlatform
2024-11-07 03:00:00
I was working on a project using Recoil for state management in React.
I needed to persist some state to localStorage, and there’s some info on how to do it in Recoil’s docs.
That works; however it doesn’t respond to state changes from other instances of your app in multiple browser tabs.
If you want that, you have to add the code yourself by leveraging the storage event.
Or, you can just copy the code I made to do it.
import { AtomEffect } from 'recoil';
/**
* Given a specific key, this effect will sync the value of the atom into localStorage
* and react to changes to that localStorage value across other tabs/windows.
*
* @param key - The key used in localStorage
*/
export const localStorageEffect =
<T>(key: string): AtomEffect<T> =>
({ setSelf, onSet, resetSelf }) => {
// On load, if there's a value in localStorage, set the atom
const savedValue = localStorage.getItem(key);
if (savedValue != null) {
setSelf(JSON.parse(savedValue));
}
// Subscribe to changes in the atom and update localStorage
onSet((newValue, _, isReset) => {
isReset ? localStorage.removeItem(key) : localStorage.setItem(key, JSON.stringify(newValue));
});
// When the value changes in localstorage (from another tab), update the atom
const handleStorageChange = (event: StorageEvent) => {
if (event.key === key) {
if (event.newValue === null) {
resetSelf();
} else {
const newValue = JSON.parse(event.newValue);
setSelf(newValue);
}
}
};
window.addEventListener('storage', handleStorageChange);
return () => {
window.removeEventListener('storage', handleStorageChange);
};
};
Usage:
const myAtom = atom({
key: 'myAtom',
default: 1,
effects: [
localStorageEffect('my-atom-local-storage-key'),
]
});
Happy coding!
2024-11-05 03:00:00
Take a look at these two animated gifs.
First:
Second:
Can you tell the difference between them?
Do you care?
If not, we might not be a good fit.
#designEngineering
Reply via: Email :: Mastodon :: Twitter
Tagged in: #designEngineer
2024-11-03 03:00:00
Every once in a while, I’ll have a post gain traction over on ye ole’ orange site (Hacker News).
I find out about it because my analytics digest will get a yuge uptick in page views.
What’s interesting is all the referral sources that show up in my analytics. The Hacker News is always at the top, but then after it comes a bunch of clones or related “scraped tech news” sites.
I sometimes click through just to see them and marvel at what an interesting, diverse place the web is and all the people building on it.
Here’s a list of the ones that showed up in my analytics recently:
While I personally don’t spend a lot of time on Hacker News, I kinda love that the site exists, gets so much traffic, and AFAIK the owners aren’t actively seeking to make every last pageview happen on their domain (news.ycombinator.com
).
I kinda love that there are still places on the web where people can explore creating alternative experiences without being shut down because they are outside the officially-sanctioned environment.
Reply via: Email :: Mastodon :: Twitter
Related posts linking here: (2024) Captchas Turned Notification Exploits
2024-10-31 03:00:00
Here’s Ben Nadal quoting Dave Farley:
I've come to the belief that the only definition of quality in code that makes any sense is our ability to change the code. If it's easy to change, it's high quality; if it's hard to change, it's not.
Then Ben comments:
I'm sure that some people will have the reaction that such an outlook is nothing more than an excuse for not doing things the "right way". But, I think that's exactly what I love about this insight—that it separates out the academia of software development from the pragmatic realities of the world. Sometimes, the sub-optimal way is actually the way that makes the code easiest to work with.
Love it.
The thing about software — and life really — is that whatever you’re doing, you’re undoubtedly doing it wrong. You’re human. You make mistakes. You’re not perfect.
If you’ve been practicing whatever you’re doing for a long time, you’re probably making fewer mistakes. But you’re still making ’em.
For me, this is true of basically everything I’ve tried in my life, from cooking to sports to software.
When I start, I’m usually wrong in very profound ways. The cookies melt to discs when baking. My golf shot is a complete shank. My code is total spaghetti.
But those results (hopefully) teach me something, so the next time I cook, or swing a club, or write some code, I approach things differently.
Given that I’m always going to make mistakes, it is of vital importance that I construct short, inexpensive feedback loops to facilitate the plethora of changes and adjustments I’ll need to make.
npm i
yourself into a dependency hole you can’t dig yourself out of.Whatever you do, make it easy to change. As easy as hitting CMD
+Z
to undo your last action on the computer — if only life had a similar undo button #amirite
?
2024-10-29 03:00:00
Bryan Braun has an interesting post about his experience with what he calls a “haunted domain”:
Being able to ascertain the reputation and vitality of a domain is an intriguing problem.
At a societal level, it’s not really a problem we’ve had to wrestle with (yet). Imagine, for example, 200 years from now when somebody is reading a well-researched book whose sources point to all kinds of domains online which at one point were credible sources but now are possibly gambling, porn, or piracy web sites.
If you take the long view, we’re still at the very beginning of the internet’s history where buying a domain has traditionally meant you’re buying “new”.
But what will happen as the lifespan of a domain begins to outpace us humans? You’re going to want to know where your domain has been.
The “condition” of a domain could very well become a million dollar industry with experts. Similar to how we have CARFAX vehicle history reports, domain history reports could become standard fare when purchasing a domain.
In fact, parallels to other real-world purchase verification and buyer protection programs is intriguing.
Establishing legal ownership of a vehicle through titles is something the government participates in. You’ll often hear people advertise a used vehicle as having a “clean title”, meaning it doesn’t have a salvaged or rebuilt title (which indicates a history of damage).
But how the car was used is also important. Was the car part of a fleet, e.g. a rental car? Was it owned by a private third-party its whole life? Did that person drive Uber? So. Many. Questions.
Even where the car has been is important. I remember buying a car in Las Vegas once and the dealer was telling me how people from New England frequently fly into town to buy a car. Why? Because they want a car whose lifespan had been in the dry desert and would thus be free of the effects of harsh winters (rust from snow/salted roads, etc).
When you buy a house, getting an inspection is pretty standard fare (where I live). Part of the home buying process includes paying an inspector to come in and assess the state of the home — and hopefully find any problems the current owners either don’t know about or are keeping from you.
But the history of the home is often important too. Was it a drug house? Was it a rental? An Airbnb?
Houses have interesting parallels to domains because their lifespans are so much longer than other things like cars (my current house was built in the 1930’s). Homes can go through many owners, some of whom improve it over time while others damage it.
You know those home renovation shows? The nerd version of that would be a “domain renovation” show where people buy old domains, fix them up (get them whitelisted with search engines again, build lots of reputable inbound links, etc.), and then flip them for a good price.
What I love most about this world is the verbiage around the various grading systems, such as:
Even within “Mint” there are various categorizations such as:
Can you imagine something similar for domains?
Honestly, I don’t really have anything else to say about this, lol. It’s simply fun to think about and write down what comes to mind.
That said, it wouldn’t surprise me if a standardized grading system with institutional verification rises up around the world of domains. URLs are everywhere — from official government records to scrawled on the back a door in a public restroom — and they’ll be embedded in civilization for years to come. (Even more so if domains become the currency of online handles!)
Today usa.gov
is backed by the full faith and credit of the United States Government. But a few hundred years from now, who knows? Maybe it’ll be an index for pirated music.
Whatever happened to romanempire.gov
?