Categories
Funemployed Software Development

Laravel Url Shortener FTW

Where I discuss creating a bitly style self-hosted URL shortener written for the Laravel framework.

While working through my funemployment (which wasn’t fun, but maybe I can convince myself) I started a side-project to (re-)learn Laravel. The last time I used Laravel was version 4 or 5 — it’s now v. 12 so there’s been a few changes.

My need to learn combined with my need to be more frugal lately (💸 no paychecks). I’ve been brainstorming methods limiting websites dependencies on databases (which typically incur an increased cost from additional hardware requirements). And given one of my websites lost it’s hosting and used to have YOURLS deployed on it I wanted an alternative I could play around with.

Sidenote: a URL shortener essentially allows a mapping from a site you own (e.g. n3f.co) to a much larger or longer URL. There really isn’t much use for it, but I enjoy the vanity aspect (controlling my own), making short urls as bookmarks, sharing links, and tracking clicks.

The actual implementation was pretty simple. Laravel made creating the routes really easy and I just had to create a couple react components and add them to the default project. I thought this might be a fun project to try with Rails and Go as well if I ever get the time (and I wouldn’t even have to do much to the frontend).

Route::controller(UrlController::class)->group(function () {
    Route::post('urls', 'store')->name('urls.store');
    Route::patch('urls/{id}', 'edit')->name('urls.edit');
    Route::get('urls/{id}/stats', 'stats')->name('urls.stats');
    Route::delete('urls/{id}', 'destroy')->name('urls.destroy');
})->middleware(['auth', 'verified', 'throttle:10,1']);
Code language: PHP (php)
Url Shortener edit form
Url Shortener edit form
set an expiration

Right now the feature set isn’t comprehensive, but you can currently:

  • Create a short url
  • Define the alias or short code. (Or just use an apparently randomly generated one)
  • Set an expiration for a defined url (i.e. after a certain timestamp the redirection to the target will stop working)
  • Edit or delete your defined urls
  • Currently, I’m preserving all requests, but I need additional analytics processing and UI to surface results.
  • Uses any database Laravel supports including SQLite (which is free–this results in roughly 50% savings for me 🤑)

Features I need to add (or would like to):

  • search
  • stats (other than simple clicks)
  • QR code sharing.
  • bookmarklets (are these even used any more?)

I’m curious if anyone else would find this project helpful. Would you use a link shortener? If so, what features would you like to see?

Categories
Funemployed Software Development

Deploying Laravel application to nearlyfreespeech.net

I recently created a Laravel application as a side-project to re-learn the framework. (I’ll post more about it later. It’s a URL Shortener). The documentation for getting this application was mostly correct. However, I discovered at least one issue because I wanted to save money and use a SQLite database instead of the more costly MySQL one.

Transfer files

Get your files over to the site by rsync-ing the directory to the protected area:

# Replace $ACCOUNT with your NFSN account username and 
# $HOST with your assigned server hostname.
$ rsync -avz --exclude='.git' \
  --exclude='node_modules' \
  --exclude='storage/logs/*' \
  --exclude='storage/framework/cache/*' \
  --exclude='storage/framework/sessions/*' \
  --exclude='storage/framework/views/*' \
  --exclude='.env' --exclude='vendor' \
  --exclude='.DS_Store' --exclude='*.log' \
  . $ACCOUNT@$HOST:/home/protected/laravel-app/Code language: Bash (bash)

Update .env

Depending on your application this could be complicated or easy. Copy your .env.example to .env and make any changes necessary.

Set file system permissions

I found 3 directories I needed to update, if you aren’t using the default sqlite database you can skip that one.

#!/bin/bash

directories=(
    "database"        # ⚠️ where the sqlite database goes
    "storage"         # logs/cache
    "bootstrap/cache" # cache (duh)
)

for directory in "${directories[@]}"; do
    chown -R web "$directory"
    chmod -R 775 "$directory"
doneCode language: PHP (php)

Get public directory configured

The public directory is locked down so it can’t be moved or overwritten. I moved everything in my Laravel app’s public directory into the nearlyfreespeech one, deleted the empty directory, and then linked to the canonical one. Effectively it lets the public directory be in 2 places at the same time.

From inside the laravel-app directory:

$ ln<span style="background-color: initial; font-size: inherit; text-align: initial; text-wrap-mode: wrap; color: inherit; letter-spacing: -0.015em;"> -s ../../public public</span>Code language: Bash (bash)

Rebuild application

You can forego this step if you transfer your vendor directory and run npm run build first too. From the Laravel app directory:

  1. composer install
  2. npm install
  3. npm run build
  4. php artisan optimize

.htaccess

Either move or copy the provided .htaccess file to public. Laravel requires its own .htaccess rules for routing (otherwise all requests won’t be directed through index.php).

Conclusion

That should be it. Test your application and get it running. I found a problem with a models generated attributes–💡I had to add the $appends property–but in general it seems to be working well.

Categories
Funemployed Software Development

Display Open Graph data with Link Preview Card Block

A couple weeks ago, I started entertaining offers for employment. As part of that effort I spun up my old resume site, dusted off the cobwebs and updated the content. After it was all bright and shiny, I sent the link to my wife over text. She’s not an engineer but she is a fantastic writer. I was disappointed it didn’t generate a cool picture and excerpt as many links do these days. Why not?

I’ll share you the google (or AI conversation depending on your preferences), but I found the mechanism to create that content is provided by an “open graph protocol”. Really this “protocol” (by Meta™) is nothing more than adding a couple of lines to the website’s HTML. (There is also a competing protocol/standard used by Twitter/X). They’re both pretty easy to add.

After adding a couple of fields to my website, behold:

Apple doesn’t show a description; just picture, title and link.

If you’re interested in adding support for your own site, that’s not what this post is about 😆.

I believe this is a great way to link content. It not only shows what to expect from a link–a quick title and description–it also adds a large click target. When I went to create my post, I was disappointed I couldn’t find a plugin supporting this card data on WordPress sites. (It’s probably already there, but I figured it would be fun to roll my own rather than use someone else’s).

After a quick coding sesh, I threw together an early version. Now with the Link Preview Card plugin (wordpress.org), you too can add these cards to your posts and pages.

Result

I’m fond of the slight zoom when you hover over it.

Features:

  • Enter a link.
  • Caches site data (via an API call).
  • Displays open graph card (with slight zoom on hover)

For a general proof of concept this is definitely workable. I thought it was fun to play with. I used AI to evaluate better testing approaches to plugin development (still haven’t found a great method for doing this). I have a list of TODO’s that are still low hanging fruit, but would love any thoughts for new features.

If you have a site, give it a spin and kick the tires. Let me know how it goes.

Categories
Funemployed Software Development

Hard Working Engineer Available

I just shared this on Facebook and thought I should post here too: for those that don’t know on April 2, I was laid-off (from a job I loved; and with nearly 20% of the company).  I’ve been looking for a new job non-stop for the last 3 months, but this market is pretty brutal.  If you know of anyone looking for a senior or staff software engineer, let me know, or point them to 👇

Remote or SoCal would be preferred, but I’m open to anything.