This is part 5 of my beginner journey, and I owe you an apology first.
I went quiet for about a month. This is my first real project, and I did not know how much time it would take. For people who build things every day, a lot of this will look basic. For me it was a big deal, and I did not want to post updates until I had something honest to say.
If you are new here, the earlier parts are part 1, part 2, part 3 and part 4.
The name took the longest
I started with the name Fontly and deployed the site under it. Then I did my research. I found that domains in the same niche already existed, and so did apps with similar names. I started worrying about brand and copyright problems. Then I learned that people can actually take legal action over a name, and that made the worry bigger.
So I kept searching. I wanted a name that was short, easy to say, and related to the site. I did not want a long name. Every option I liked had some problem.
And there was a quiet pressure on top of it. Why was I taking so long to decide one thing? That feeling made me overthink even more.
In the end I said: enough. Close your eyes and pick Fonti.
Renaming after I had already deployed
Here is the funny part. The site was already deployed under the old name, so I had to go back and change everything to Fonti.
And a confession. In part 4 I already talked about the new name, but at that time I had not even bought the domain. When it was finally time to buy it, the overthinking came back and it took more time again. This time I stopped thinking and took action.
It might sound weird, or even funny. But I think this is what happens when you are new to something. A small decision feels huge when you are afraid of getting it wrong.
Then my PC died
In the middle of all this, the motherboard and the processor on my PC both died. I replaced them and started again.
It was frustrating. But it reminded me of part 1 and part 2. When I get stuck, my first instinct is to think more. Every time I took action instead, things moved again.
I chased speed, then stopped
Speed was the top priority for my site. I started chasing it hard, and I reached a level that most beginners do not even think about.
Then I stopped. Overdoing anything is unhealthy, and speed is no exception. After a certain point it becomes overkill: every small gain costs more time than the one before it, and that time was being taken from things that still needed finishing. A faster site is nice. A finished site is better. So I decided that "fast and good enough" is the goal, not "perfect".
One technical thing from this month
I also overthought whether my code was correct. After part 4 I had an exception list for the Unicode holes, and I did not want to trust my memory. So I wrote a script that runs every style on A to Z, a to z and 0 to 9, and checks two things:
- Never U+FFFD: the replacement character means something went wrong.
- Never unchanged: a letter should not come back as itself, unless I declared on purpose that it should.
Here is the idea, simplified:
function checkOne(style, plain, generated, kind) {
const cp = generated.codePointAt(0);
if (cp === 0xfffd) {
failures.push({ subject: style.id, cause: `${kind} "${plain}" produced U+FFFD` });
}
if (generated === plain && !isDeclared(style, plain, kind)) {
failures.push({ subject: style.id, cause: `${kind} "${plain}" passed through unchanged` });
}
}
I ran it:
RESULT: PASS. 17 styles, all uppercase/lowercase/digit characters verified. 8 decorations, every prefix and suffix character verified.
I felt safe. But a passing test only tells me it did not find a problem. It does not tell me it was able to find one.
So I tested the test. In my script style, each exception lives in a substitutions list. I deleted one line, B: 0x212c, which brings back the exact bug from part 4. Then I ran the script again:
RESULT: PASS. 17 styles, all uppercase/lowercase/digit characters verified. 8 decorations, every prefix and suffix character verified.
It still passed. And the line for B in the output said:
B -> (U+1D49D)
That is a code point in one of the holes. The bug was back, and my test was happy.
The reason is simple. U+1D49D is not U+FFFD, and it is not the same as the plain B. JavaScript accepted the number without complaint, because String.fromCodePoint(0x1D49D) gives a perfectly valid string. The empty box only appears later, when a screen tries to draw it. As far as I can tell, U+FFFD shows up when text is decoded from broken data, not when you build a string from a number. So my first check could never catch this.
The fix was to ask Unicode directly. JavaScript regular expressions have a property for it: \p{Cn} means "a code point that has not been assigned".
const UNASSIGNED = /\p{Cn}/u;
if (UNASSIGNED.test(generated)) {
failures.push({
subject: style.id,
cause: `${kind} "${plain}" produced ${codePointHex(generated)}, a code point Unicode has not assigned`,
});
}
With the line still deleted, the script now says:
RESULT: FAIL. 1 failure(s):
[script] uppercase "B" produced U+1D49D, a code point Unicode has not assigned
I put the line back and ran it once more. PASS, and this time it means something.
Two honest limits. First, \p{Cn} depends on the Unicode version inside whatever runs the code. On my computer, Node reports Unicode 17.0 (process.versions.unicode), and an older runtime might think a newer character is unassigned. So I only run this check on my own machine, never in the browser. Second, assigned does not mean visible: a valid character can still show as a box on a device whose fonts do not have it. So PASS means no holes. It does not mean it works everywhere.
What I learned
- Overthinking costs more than a small mistake: a name does not need to be perfect. It needs to be good enough to start.
- Things break in boring ways: a dead PC and a rename took as much time as any clever bug.
- Break your code on purpose, once: if the test does not fail, it was not protecting you.
What is next
I have been building more than I have been posting. In the next part I will show you the site live, and tell you the full story of how it came together.
One question for you: what is one decision you overthought on your first project, and how did you finally make it?
Top comments (0)