<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Umair Shakoor</title>
    <description>The latest articles on Forem by Umair Shakoor (@unseenumair).</description>
    <link>https://forem.com/unseenumair</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2905443%2Ff67f7e7b-ef12-4562-a6b6-813a9a15433a.jpg</url>
      <title>Forem: Umair Shakoor</title>
      <link>https://forem.com/unseenumair</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/unseenumair"/>
    <language>en</language>
    <item>
      <title>How I Built Expiring Links With Zero Backend (React + TypeScript Only)</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Wed, 29 Apr 2026 02:12:35 +0000</pubDate>
      <link>https://forem.com/unseenumair/how-i-built-expiring-links-with-zero-backend-react-typescript-only-17cp</link>
      <guid>https://forem.com/unseenumair/how-i-built-expiring-links-with-zero-backend-react-typescript-only-17cp</guid>
      <description>&lt;p&gt;Most "expiring link" tools work the same way: generate a link, store the destination and expiry in a database, check the database on every click, redirect or block accordingly.&lt;/p&gt;

&lt;p&gt;That's the obvious approach. It's also the one that requires a backend, a database, server costs, and a breach surface.&lt;/p&gt;

&lt;p&gt;I had a constraint: React + TypeScript only, deployed on Vercel, no Node.js, no database, no backend whatsoever.&lt;/p&gt;

&lt;p&gt;So I had to find a different way.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Core Idea: Put Everything in the URL
&lt;/h2&gt;

&lt;p&gt;Instead of storing link data on a server, encode it directly into the URL itself.&lt;/p&gt;

&lt;p&gt;When a user creates an expiring link, the app:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Takes the destination URL&lt;/li&gt;
&lt;li&gt;Takes the expiry timestamp (Unix ms)&lt;/li&gt;
&lt;li&gt;Combines them into a JSON object&lt;/li&gt;
&lt;li&gt;Encodes it with &lt;code&gt;btoa()&lt;/code&gt; (base64)&lt;/li&gt;
&lt;li&gt;Appends it as a URL parameter&lt;/li&gt;
&lt;li&gt;Shortens the full URL via TinyURL's API
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;destinationUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;expiryTimestamp&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;encoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;btoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;longUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://onetimelink.vercel.app/r?d=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;encoded&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Then shorten&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shortUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;shortenWithTinyURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;longUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When someone visits the short link, TinyURL expands it back to the long URL. The React app decodes the parameter client-side:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URLSearchParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;encoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;d&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;encoded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Invalid link&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;atob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;encoded&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Expired — show expiration screen&lt;/span&gt;
    &lt;span class="nf"&gt;setExpired&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Valid — redirect&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Malformed link&lt;/span&gt;
  &lt;span class="nf"&gt;setInvalid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No database query. No server call. No stored data anywhere.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Works
&lt;/h2&gt;

&lt;p&gt;The link carries its own expiry inside itself. The server never needs to know anything. The decision to redirect or block happens entirely in the browser, client-side, on every click.&lt;/p&gt;

&lt;p&gt;This has some interesting properties:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zero storage = zero breach surface.&lt;/strong&gt; There's no database of sensitive links sitting on a server somewhere. The data exists only in the URL you shared. If the URL is lost, the data is gone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No server costs.&lt;/strong&gt; The entire product runs on Vercel's free tier. No compute happens server-side on link visits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Works offline (partially).&lt;/strong&gt; If someone has the URL cached, the expiry check still works because it's just a timestamp comparison — no network request needed.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Tradeoffs
&lt;/h2&gt;

&lt;p&gt;This approach has real limitations worth being honest about.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;URL length.&lt;/strong&gt; Base64-encoding a JSON object adds characters. TinyURL handles the shortening, but the intermediate URL before shortening is long. If TinyURL's API rate limit is hit, the long URL is returned as a fallback — functional but not pretty.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No server-side validation.&lt;/strong&gt; A determined user could decode the base64, modify the expiry timestamp, re-encode it, and create a "non-expiring" version of the link. For most use cases this doesn't matter — the threat model is casual oversharing, not adversarial attacks. But it's worth knowing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No analytics.&lt;/strong&gt; Since nothing is stored server-side, there's no way to know how many times a link was clicked. You get one-directional expiry enforcement, not a dashboard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can't revoke early.&lt;/strong&gt; Once a link is created, it expires when it expires. There's no mechanism to kill it early because there's no server-side record to delete.&lt;/p&gt;




&lt;h2&gt;
  
  
  What It's Actually Good For
&lt;/h2&gt;

&lt;p&gt;This architecture is a good fit for the specific problem it solves: a freelancer or agency owner sharing something sensitive with a client, once, with a defined window.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Temporary login credentials for a handoff&lt;/li&gt;
&lt;li&gt;A staging environment link during a review period&lt;/li&gt;
&lt;li&gt;A private document with a natural end date&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For these use cases, the limitations above don't matter. The client clicks once, gets what they need, and after the window closes the link is dead.&lt;/p&gt;

&lt;p&gt;For anything requiring analytics, multi-click tracking, or early revocation — you need a proper backend. This approach deliberately trades those features for zero storage and zero complexity.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;React + TypeScript&lt;/li&gt;
&lt;li&gt;Vite&lt;/li&gt;
&lt;li&gt;Vercel (free tier)&lt;/li&gt;
&lt;li&gt;TinyURL API (free tier, no auth required)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;btoa()&lt;/code&gt; / &lt;code&gt;atob()&lt;/code&gt; for encoding — built into every browser, no library needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Total server infrastructure cost: $0.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;If you're building something where users need to share sensitive links temporarily, the approach above is a legitimate alternative to a full backend for certain use cases.&lt;/p&gt;

&lt;p&gt;The live implementation is at &lt;a href="https://onetimelink.vercel.app" rel="noopener noreferrer"&gt;onetimelink.vercel.app&lt;/a&gt; — free to use, no account needed.&lt;/p&gt;

&lt;p&gt;More on the architecture and the product direction on the &lt;a href="https://onetimelink.vercel.app/blog" rel="noopener noreferrer"&gt;OneTimeLink blog&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Still building in public. 408 organic users, $0 revenue, first paying customer is the only milestone that matters right now. Follow along if you want the unfiltered version.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>I Abandoned My Side Project. 210 Strangers Found It Anyway.</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Thu, 23 Apr 2026 04:30:24 +0000</pubDate>
      <link>https://forem.com/unseenumair/i-abandoned-my-side-project-210-strangers-found-it-anyway-202i</link>
      <guid>https://forem.com/unseenumair/i-abandoned-my-side-project-210-strangers-found-it-anyway-202i</guid>
      <description>&lt;p&gt;I built a tool in React + TypeScript, got frustrated with it, and moved on to other ideas.&lt;/p&gt;

&lt;p&gt;Three months later I opened Google Search Console out of curiosity.&lt;/p&gt;

&lt;p&gt;6,700 impressions. 283 clicks. Position 6.5 on Google.&lt;/p&gt;

&lt;p&gt;For a project I had completely abandoned.&lt;/p&gt;




&lt;h2&gt;
  
  
  The backstory
&lt;/h2&gt;

&lt;p&gt;This was my second SaaS attempt. I'd already failed once and was deep in the "just ship something" mindset.&lt;/p&gt;

&lt;p&gt;The idea was simple: URL shortener with expiry. When the time runs out, the link dies. No backend. No database. No auth.&lt;/p&gt;

&lt;p&gt;I built it, looked at TinyURL and Bitly, thought &lt;em&gt;"these already exist and they're worth $48M, I can't compete"&lt;/em&gt; — and moved on.&lt;/p&gt;

&lt;p&gt;That was a mistake in reasoning. More on that in a second.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4trs1m9094pvjc14m45n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4trs1m9094pvjc14m45n.png" alt="Google Search Console Performance ScreenShot of oneTimeLink" width="800" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The accidental traction
&lt;/h2&gt;

&lt;p&gt;When I came back to check on it, the keywords ranking were interesting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"expire link generator"&lt;/li&gt;
&lt;li&gt;"temporary link"&lt;/li&gt;
&lt;li&gt;"one time use link"&lt;/li&gt;
&lt;li&gt;"expiring link"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These aren't brand searches. These are &lt;strong&gt;problem-aware searches.&lt;/strong&gt; People knew they had a problem and were looking for a solution.&lt;/p&gt;

&lt;p&gt;I set up GA4. Within 24 hours:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;45 users&lt;/li&gt;
&lt;li&gt;20% generated a link&lt;/li&gt;
&lt;li&gt;72.5% bounce rate (bad, but the intent traffic was real)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The bounce rate told me the landing page was wrong. The usage rate told me the problem was real.&lt;/p&gt;




&lt;h2&gt;
  
  
  The technical decision that made this possible
&lt;/h2&gt;

&lt;p&gt;Here's the part developers find interesting.&lt;/p&gt;

&lt;p&gt;I had a constraint: no backend. I was building in React + TypeScript only, deployed on Vercel. No Node.js, no database, no server.&lt;/p&gt;

&lt;p&gt;So how do you build expiring links without storing anything?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Encode everything in the URL itself.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When a user creates a link with an expiry, the app:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Takes the destination URL&lt;/li&gt;
&lt;li&gt;Takes the expiry timestamp&lt;/li&gt;
&lt;li&gt;Encodes both into a single URL-safe string&lt;/li&gt;
&lt;li&gt;Passes that to TinyURL's API to shorten it&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When someone visits the link:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The short URL expands to the encoded long URL&lt;/li&gt;
&lt;li&gt;The app decodes the destination and expiry from the URL parameters&lt;/li&gt;
&lt;li&gt;Checks current timestamp against expiry&lt;/li&gt;
&lt;li&gt;If expired: shows expiration screen. If valid: redirects.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No database query. No server call. No stored data. &lt;strong&gt;The link carries its own expiry inside itself.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Simplified encoding logic&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;destinationUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;expiryTimestamp&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;encoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;btoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;longUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://onetimelink.vercel.app/r?d=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;encoded&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Then shorten via TinyURL API&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shortUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;shortenWithTinyURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;longUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This has a counterintuitive benefit: &lt;strong&gt;zero server storage = zero breach risk.&lt;/strong&gt; There's nothing to hack. The data lives in the URL and nowhere else.&lt;/p&gt;

&lt;p&gt;For freelancers sharing sensitive client links, that's not a technical footnote. That's the entire value proposition.&lt;/p&gt;




&lt;h2&gt;
  
  
  The validation mistake I almost made
&lt;/h2&gt;

&lt;p&gt;After seeing the traction, my first instinct was to look at Google Drive's sharing features and think &lt;em&gt;"people can already control access there, my expiry idea isn't a moat."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I almost pivoted away from it.&lt;/p&gt;

&lt;p&gt;Instead I sent &lt;strong&gt;21 DMs&lt;/strong&gt; to freelancers, founders, and CTOs asking one question:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"When you send a client a password or sensitive link — what do you actually do?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Three replies came back:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Djune (Founder &amp;amp; CEO):&lt;/strong&gt; &lt;em&gt;"I encrypt it in a message with a 1-hour life span with a PIN only they know."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Uzair (Top Rated Freelancer):&lt;/strong&gt; &lt;em&gt;"I just send them a document with the credentials."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Waqas (CTO):&lt;/strong&gt; &lt;em&gt;"Yes, this is a real problem. I use 1Password sharing or split the info across two channels. If you're building something: focus on one-time access, expiry, and making it easy for non-technical clients."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That last reply rewrote my entire positioning.&lt;/p&gt;

&lt;p&gt;The insight wasn't "expiring links." The insight was &lt;strong&gt;"easy for non-technical clients."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every existing solution — 1Password sharing, encrypted messages, split credentials — requires the recipient to do something. Install an app. Enter a PIN. Have an account.&lt;/p&gt;

&lt;p&gt;OneTimeLink requires nothing from the recipient. They click. It works. Or it's expired.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq624zbkyk6fr9346f4y7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq624zbkyk6fr9346f4y7.png" alt="Google Analytics G4A overview for oneTimeLink" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I changed after validation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Repositioned headline:&lt;/strong&gt;&lt;br&gt;
Before: &lt;em&gt;"Share URLs that expire automatically"&lt;/em&gt;&lt;br&gt;
After: &lt;em&gt;"Share Sensitive Links Your Clients Can Actually Use"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bounce rate:&lt;/strong&gt; 72.5% → 51.9% after the copy change alone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Average engagement:&lt;/strong&gt; 9s → 19s.&lt;/p&gt;

&lt;p&gt;Same product. Different words. Completely different results.&lt;/p&gt;




&lt;h2&gt;
  
  
  Current state: honest numbers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;210 organic users (zero paid traffic)&lt;/li&gt;
&lt;li&gt;26 users generated at least one link (12.4% activation)&lt;/li&gt;
&lt;li&gt;5 users attempted Pro waitlist signup&lt;/li&gt;
&lt;li&gt;Revenue: $0.00&lt;/li&gt;
&lt;li&gt;Paying customers: 0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm building in public because I think the honest version of this journey is more useful than the highlight reel.&lt;/p&gt;

&lt;p&gt;The next milestone is the first paying user. Not the first hundred. Just one person who values this enough to pay $7/month.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I'd do differently
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Set up analytics on day one.&lt;/strong&gt; I flew blind for months.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't confuse "utility" with "demand."&lt;/strong&gt; Useful ≠ something people will pay for.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Talk to users before building features.&lt;/strong&gt; Three DM replies taught me more than three months of solo building.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The technical constraint became the product.&lt;/strong&gt; No backend wasn't a limitation. It became the trust signal: &lt;em&gt;"nothing stored on our servers, ever."&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Try it / feedback welcome
&lt;/h2&gt;

&lt;p&gt;If you're a freelancer or developer who shares sensitive stuff with clients, I'd genuinely love brutal feedback:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://onetimelink.vercel.app" rel="noopener noreferrer"&gt;onetimelink.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What would make you actually pay $7/month for this?&lt;/p&gt;

&lt;p&gt;Drop it in the comments. I read everything.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Building OneTimeLink in public. Follow along if you want the unfiltered version.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Update — April 29, 2026
&lt;/h2&gt;

&lt;p&gt;A lot has changed since I first published this.&lt;/p&gt;

&lt;p&gt;The tool now has proper positioning, a pricing page, a waitlist, and 408 organic users in the last 28 days — still $0 revenue, still building.&lt;/p&gt;

&lt;p&gt;I've also started writing about the actual problem: why freelancers share passwords unsafely, what expiring links actually do, and how agencies handle sensitive client deliverables.&lt;/p&gt;

&lt;p&gt;If any of that is useful to you, it's all here: &lt;a href="https://onetimelink.vercel.app/blog" rel="noopener noreferrer"&gt;onetimelink.vercel.app/blog&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The most read so far: &lt;a href="https://onetimelink.vercel.app/blog/best-expire-link-generator-for-freelancers" rel="noopener noreferrer"&gt;The Best Expire Link Generator for Freelancers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Still building in public. Still at $0. First paying customer is the only milestone that matters right now.&lt;/p&gt;

</description>
      <category>buildinpublic</category>
      <category>startup</category>
      <category>webdev</category>
      <category>saas</category>
    </item>
    <item>
      <title>Git Commits</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Thu, 19 Mar 2026 12:49:58 +0000</pubDate>
      <link>https://forem.com/unseenumair/git-commits-45ci</link>
      <guid>https://forem.com/unseenumair/git-commits-45ci</guid>
      <description>&lt;p&gt;I always wonder that how those top engineers write the best commits meanwhile Le me who just commit "update" after doing tons of stuff 😂&lt;/p&gt;

&lt;p&gt;until I realized that a commit message should be satisfy :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"If someone reads this commit, will they understand the change WITHOUT opening code?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's it . &lt;/p&gt;

&lt;p&gt;Congrats, you understand what is good commit message !&lt;/p&gt;

&lt;p&gt;but when to commit ?&lt;/p&gt;

&lt;p&gt;most people like me after doing random changes commit msg "final changes" , however the real rule is :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"if you can clearly explain what you have changed till now and it is a small change then commit otherwise don't"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you have added feature of file validation instead of waiting to finish whole project then commit. Just commit on that step with "add file validation"&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;PS : Hope, this make sense . I learned this the hard way, but you are lucky to know it easily 😁&lt;/p&gt;

</description>
      <category>git</category>
      <category>bash</category>
      <category>linux</category>
      <category>todayilearned</category>
    </item>
    <item>
      <title>I got tired of opening 3 different tools just to do simple image edits.</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Mon, 09 Mar 2026 10:08:18 +0000</pubDate>
      <link>https://forem.com/unseenumair/i-got-tired-of-opening-3-different-tools-just-to-do-simple-image-edits-536i</link>
      <guid>https://forem.com/unseenumair/i-got-tired-of-opening-3-different-tools-just-to-do-simple-image-edits-536i</guid>
      <description>&lt;p&gt;So I built &lt;strong&gt;BubbleKit&lt;/strong&gt; 🫧&lt;/p&gt;

&lt;p&gt;A tiny browser tool that lets you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🖼️ Remove backgrounds&lt;/li&gt;
&lt;li&gt;📏 Resize images&lt;/li&gt;
&lt;li&gt;⚡ Export WebP fast&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Would love honest feedback 🙏&lt;/p&gt;

</description>
      <category>startup</category>
      <category>buildinpublic</category>
      <category>youtube</category>
      <category>nanobanana</category>
    </item>
    <item>
      <title>Calculator using Vanilla JavaScript</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Thu, 11 Dec 2025 13:29:00 +0000</pubDate>
      <link>https://forem.com/unseenumair/calculator-using-vanilla-javascript-1mbm</link>
      <guid>https://forem.com/unseenumair/calculator-using-vanilla-javascript-1mbm</guid>
      <description>&lt;h2&gt;
  
  
  🚀 What I Practiced
&lt;/h2&gt;

&lt;p&gt;This is a practice project to improve my skills in JS eval and DOM.  &lt;/p&gt;

&lt;h2&gt;
  
  
  💡 Project Overview
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Calculator&lt;/strong&gt; is a great practice project for JS eval and DOM.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Practiced JS eval&lt;/li&gt;
&lt;li&gt;✅ Explored amazing array Functions like includes()&lt;/li&gt;
&lt;li&gt;✅ Learned JS DOM&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔗 Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live&lt;/strong&gt; &lt;a href="https://unseenumair.github.io/calculator/" rel="noopener noreferrer"&gt;Demo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source&lt;/strong&gt; &lt;a href="https://github.com/unseenumair/calculator" rel="noopener noreferrer"&gt;Code&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;PS:&lt;/strong&gt; Any suggestions or feedback? 🤔&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Umair's Coming Soon Portfolio</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Tue, 09 Dec 2025 06:53:53 +0000</pubDate>
      <link>https://forem.com/unseenumair/umairs-coming-soon-portfolio-29hm</link>
      <guid>https://forem.com/unseenumair/umairs-coming-soon-portfolio-29hm</guid>
      <description>&lt;h2&gt;
  
  
  🚀 What I Practiced
&lt;/h2&gt;

&lt;p&gt;This is a practice project to improve my skills in &lt;strong&gt;JavaScript&lt;/strong&gt;.  &lt;/p&gt;

&lt;h2&gt;
  
  
  💡 Project Overview
&lt;/h2&gt;

&lt;p&gt;You have not seen this kind of &lt;strong&gt;Coming Soon Portfolio&lt;/strong&gt; yet&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Practiced JavaScript&lt;/li&gt;
&lt;li&gt;✅ Explored Canvas&lt;/li&gt;
&lt;li&gt;✅ Learned Ui/Ux&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔗 Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live&lt;/strong&gt; &lt;a href="https://unseenumair.github.io/" rel="noopener noreferrer"&gt;Demo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source&lt;/strong&gt; &lt;a href="https://github.com/unseenumair/unseenumair.github.io/" rel="noopener noreferrer"&gt;Code&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;PS:&lt;/strong&gt; Any suggestions or feedback? 🤔&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>portfolio</category>
      <category>frontend</category>
      <category>programming</category>
    </item>
    <item>
      <title>𝗠𝗼𝘀𝘁 𝘁𝗲𝗮𝗰𝗵𝗲𝗿𝘀 𝗗𝗢𝗡’𝗧 𝗸𝗻𝗼𝘄 𝘁𝗵𝗶𝘀 𝗮𝗯𝗼𝘂𝘁 𝗝𝗮𝘃𝗮𝗦𝗰𝗿𝗶𝗽𝘁'𝘀 finally {} 𝗯𝗹𝗼𝗰𝗸...</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Mon, 01 Dec 2025 13:25:40 +0000</pubDate>
      <link>https://forem.com/unseenumair/-finally--28id</link>
      <guid>https://forem.com/unseenumair/-finally--28id</guid>
      <description>&lt;h2&gt;
  
  
  try{} and catch{} are easy:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;try{} runs code (and prevents script crash on error)&lt;/li&gt;
&lt;li&gt;catch{} handles the error&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  But finally{} 𝗶𝘀 𝘁𝗵𝗲 𝗺𝗶𝘀𝘂𝗻𝗱𝗲𝗿𝘀𝘁𝗼𝗼𝗱 𝗼𝗻𝗲.
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Most people say:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"finally{} always runs after try{} or catch{}."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Correct… 𝗯𝘂𝘁 𝗼𝗻𝗹𝘆 𝗵𝗮𝗹𝗳 𝘁𝗵𝗲 𝘁𝗿𝘂𝘁𝗵.&lt;/p&gt;

&lt;h3&gt;
  
  
  Here’s the surprise:
&lt;/h3&gt;

&lt;p&gt;You 𝗱𝗼𝗻’𝘁 𝗻𝗲𝗲𝗱 finally{} to run code after try/catch in a simple block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The End&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could just place console.log("The End") after everything.&lt;/p&gt;

&lt;p&gt;So… what’s the real purpose of finally{}?&lt;/p&gt;

&lt;h3&gt;
  
  
  𝗧𝗵𝗲 𝗿𝗲𝗮𝗹 𝗽𝗼𝘄𝗲𝗿 𝗮𝗽𝗽𝗲𝗮𝗿𝘀 𝗶𝗻𝘀𝗶𝗱𝗲 𝗳𝘂𝗻𝗰𝘁𝗶𝗼𝗻𝘀:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

 &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;

 &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;

 &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

 &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The End&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Normally, when a function hits return, the remaining code never executes.&lt;/p&gt;

&lt;p&gt;But with finally{}, this line 𝘀𝘁𝗶𝗹𝗹 𝗿𝘂𝗻𝘀, even if both try and catch returned.&lt;/p&gt;

&lt;p&gt;That's the true magic of finally{} —&lt;/p&gt;

&lt;p&gt;It 𝗮𝗹𝘄𝗮𝘆𝘀 executes, even after a return, making it perfect for cleanup, logs, closing connections, releasing resources, etc.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I was confused about this early on, but once it clicked, it made advanced JS flow much clearer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;𝗣𝗦: Which JavaScript concept confused you the most when you first learned it?&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>discuss</category>
    </item>
    <item>
      <title>🎉 Mini Game Project Completed: Tic Tac Toe! 🕹️</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Mon, 24 Nov 2025 14:42:33 +0000</pubDate>
      <link>https://forem.com/unseenumair/mini-game-project-completed-tic-tac-toe-51in</link>
      <guid>https://forem.com/unseenumair/mini-game-project-completed-tic-tac-toe-51in</guid>
      <description>&lt;p&gt;I'm excited to share that I've completed a &lt;strong&gt;Mini Game Project&lt;/strong&gt; – &lt;strong&gt;Tic Tac Toe&lt;/strong&gt;!  &lt;/p&gt;

&lt;p&gt;It might sound simple, but small projects like this are essential for building a &lt;strong&gt;strong foundation&lt;/strong&gt; as a Frontend Developer 💻. They prepare you for bigger, more complex projects.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Why I built it
&lt;/h2&gt;

&lt;p&gt;Most web-based Tic Tac Toe games lack a clean, user-friendly UI – so I decided to create one! 🎨  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fun fact: It's a &lt;strong&gt;2-player game&lt;/strong&gt;, perfect to play with friends 👯
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 &lt;strong&gt;Try it out and share your feedback or suggestions!&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live Preview:&lt;/strong&gt; &lt;a href="https://us-tictactoe.netlify.app/" rel="noopener noreferrer"&gt;us-tictactoe.netlify.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source Code:&lt;/strong&gt; &lt;a href="https://github.com/unseenumair/games/tree/main/TicTacToe" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>tictactoe</category>
      <category>beginners</category>
      <category>100daysofcode</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>No other Icons Library Needed 🥶</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Fri, 21 Nov 2025 02:46:49 +0000</pubDate>
      <link>https://forem.com/unseenumair/no-other-icons-library-needed-4500</link>
      <guid>https://forem.com/unseenumair/no-other-icons-library-needed-4500</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Iconify&lt;/strong&gt; is here.
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It is &lt;strong&gt;OpenSource&lt;/strong&gt; All in one Modern Ui Icons library.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  They also have a CDN :
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://code.iconify.design/iconify-icon/3.0.0/iconify-icon.min.js"&lt;/span&gt; &lt;span class="na"&gt;defer&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Just Paste this script in html head tag&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Copy Web Components from
&lt;/h2&gt;

&lt;p&gt;🔗 &lt;a href="https://icon-sets.iconify.design/" rel="noopener noreferrer"&gt;Iconify&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;by searching for your desired icon. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Then, paste that  tag in your body , whereever you wanna use it and Boom 🤯.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tip :
&lt;/h3&gt;

&lt;p&gt;Use CSS &lt;strong&gt;Font-Size&lt;/strong&gt; to cusomtize the size of the icon and you can also do that by giving width &amp;amp; height to iconify-icon tag.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Have you any suggestions or feedback?&lt;br&gt;
Tell us in comments, I love it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;🫠 Like &amp;amp; Follow us - If you want these kind of more things...&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>iconify</category>
      <category>webdev</category>
      <category>100daysofcode</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Startup Failure</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Sat, 15 Nov 2025 02:46:02 +0000</pubDate>
      <link>https://forem.com/unseenumair/startup-failure-2n88</link>
      <guid>https://forem.com/unseenumair/startup-failure-2n88</guid>
      <description>&lt;p&gt;This Startup &lt;strong&gt;Dialo3 Studio&lt;/strong&gt; failed and the best lessons from &lt;strong&gt;mistakes&lt;/strong&gt; I learned are : &lt;/p&gt;

&lt;h2&gt;
  
  
  I Entered the Market without proper research and knowledge
&lt;/h2&gt;

&lt;p&gt;If you have enough money to invest in your idea, you can hire top talent and you don't necessarily have good &lt;strong&gt;knowledge&lt;/strong&gt; about the business but for someone who is starting as a Solo Founder with no money could not hire top talent . So, that solo founder, only have option to first gain enough knowledge about that business, its target audience etc then launch. Otherwise, there are very few chances of Success&lt;/p&gt;

&lt;h2&gt;
  
  
  I was not passionated about that business idea and I just started it for some financial purposes
&lt;/h2&gt;

&lt;p&gt;Any Business to be Successful takes a lot of time. There is always a process of grinding, consistency, patience, hardwork etc. All those could not be carried by a person who just started a business and thinking of it like a &lt;strong&gt;shortCut&lt;/strong&gt; way of earning. Yes, it is true that Business has potential to make you rich but that is not &lt;em&gt;overnight Success&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  First Sale is the Hardest Step
&lt;/h2&gt;

&lt;p&gt;When I see that in 1 - 2 months, things are not happening according to my Expectations, I quit. Later, I realize that first sale is the hardest step.&lt;br&gt;
Bcz after that, you know exactly which &lt;strong&gt;things works&lt;/strong&gt; and which not.&lt;/p&gt;

&lt;p&gt;Any Suggestions and your Opinions about how a startup is failed mainly due to ... , drop in comments. I love that .&lt;/p&gt;

</description>
      <category>startup</category>
      <category>failure</category>
      <category>beginners</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Forget Sensitive URls after Share !</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Sun, 09 Nov 2025 09:14:15 +0000</pubDate>
      <link>https://forem.com/unseenumair/forget-sensitive-urls-after-share--1b8o</link>
      <guid>https://forem.com/unseenumair/forget-sensitive-urls-after-share--1b8o</guid>
      <description>&lt;p&gt;We just launched OneTimeLink on &lt;strong&gt;Product Hunt&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OneTimeLink&lt;/strong&gt; helps you create links that auto-expire for secure, temporary sharing.&lt;br&gt;
If you're curious, feedback and thoughts are welcome.&lt;/p&gt;

&lt;p&gt;Website : &lt;a href="https://onetimelink.vercel.app/" rel="noopener noreferrer"&gt;onetimelink&lt;/a&gt;&lt;br&gt;
Product Hunt : &lt;a href="https://www.producthunt.com/products/onetimelink-2?utm_source=other&amp;amp;utm_medium=social" rel="noopener noreferrer"&gt;onetimelink&lt;/a&gt;&lt;/p&gt;

</description>
      <category>product</category>
      <category>startup</category>
      <category>webapp</category>
      <category>security</category>
    </item>
    <item>
      <title>Last Post 🥲</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Tue, 05 Aug 2025 12:49:38 +0000</pubDate>
      <link>https://forem.com/unseenumair/last-post-55jj</link>
      <guid>https://forem.com/unseenumair/last-post-55jj</guid>
      <description>&lt;p&gt;🌪️ I used to think…&lt;br&gt;
“If I just shout loud enough online, maybe someone will hear me.”&lt;/p&gt;

&lt;p&gt;I posted with ❤️, with 🔥, with truth...&lt;br&gt;
But the world just kept scrolling. 📱&lt;/p&gt;

&lt;p&gt;So I’ve decided to stop.&lt;br&gt;
Not because I gave up.&lt;br&gt;
But because I finally understood something deeper:&lt;/p&gt;

&lt;p&gt;🤫 &lt;strong&gt;Real power is built in silence.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I’m not disappearing.&lt;br&gt;
I’m preparing. 💻🧠&lt;/p&gt;

&lt;p&gt;One day — when the world hears a new name shake the ground ⚡&lt;br&gt;
You’ll remember the one who went quiet...&lt;/p&gt;

&lt;p&gt;...and returned with thunder. ⚔️⚡🌍&lt;/p&gt;

&lt;p&gt;— &lt;strong&gt;Umair Shakoor&lt;/strong&gt;&lt;br&gt;
👣 Building in Silence.&lt;br&gt;
🕶️ See you on the other side...&lt;/p&gt;

</description>
      <category>lastpost</category>
      <category>beginners</category>
      <category>career</category>
      <category>news</category>
    </item>
  </channel>
</rss>
