Wes Ellis./ a personal notebook
Technology. Stories. Side projects.
A few things worth writing down.
← Back to Side Projects

Side Projects

Custom Homepage: A New Tab Page With Unsplash Photos and Real Thumbnails

A beige vintage home computer keyboard sitting in front of a crowded bookshelf.

Part 3 of the thread Desktop tinkering

PROJECT AT A GLANCEOpen source
What it is
Browser extension
My role
Creator
Year
2025
Built with
  • JavaScript
  • HTML
  • CSS
  • Chrome Manifest V3
  • Unsplash API
THE SHORT VERSION4 points
  • Replaces Chrome's new tab page with the time and date, a random Unsplash photo and a grid of your sites.
  • Shortcuts get screenshot thumbnails, falling back to local capture and then favicons when a site won't cooperate.
  • You bring your own Unsplash access key; a screenshot service key is optional.
  • It's a demo project: it works, but it isn't on the Chrome Web Store.

You open a new tab dozens of times a day, and Chrome's default one is a search box and some tiles it picked for you. I wanted something closer to a desk: the time, a nice photo, and the sites I actually use, big enough to hit without aiming.

custom-homepage is that, as a Chrome extension. It's plain HTML, CSS and JavaScript, eight files in all, and it takes over the new tab page through Chrome's chrome_url_overrides setting.

What it does

Four things, really:

  • A clock with the current time and date.
  • A background photo pulled at random from Unsplash, swapped every 30 minutes.
  • A shortcut grid of the sites you add, each with a visual preview.
  • Local storage for all of it, so your list lives in Chrome and nowhere else.

Adding a site is a "+" button, a name and a URL. The extension grabs a thumbnail, you click Add, and it's saved. Hover over a tile and click the "×" to get rid of it.

How the thumbnails work

Screenshots of other websites are the fiddly bit, because plenty of sites don't want to be captured. So the extension tries three things in order:

  1. A screenshot API service, if you've configured one.
  2. Local capture with HTML2Canvas.
  3. Google's favicon service, which always works but looks a bit rough at tile size.

The screenshot service is optional. The README lists ScreenshotMachine, HTMLCSStoImage and ApiFlash as options, and without one you'll land on local capture or the favicon.

The grid

The layout scales with the window, which matters more than you'd think on an ultrawide:

Screen width Columns
Under 768px 3
768 to 1023px 4
1024 to 1439px 5
1440 to 1919px 6
1920px and up 8

Colors are CSS custom properties in styles.css, so changing the text or shadow color is a one-line edit. The screenshot size (1024 by 1024 by default) and the Unsplash search term ("nature" out of the box; try "abstract", "city" or "space") are constants at the top of script.js.

Using it

Get an access key from the Unsplash developer site by creating an application. Then open script.js and drop your keys into the two constants at the top:

const UNSPLASH_ACCESS_KEY = 'YOUR_UNSPLASH_KEY_HERE';
const SCREENSHOT_API_KEY = 'YOUR_SCREENSHOT_KEY_HERE'; // Optional

Load it like any unpacked extension: go to chrome://extensions/, turn on Developer mode, click "Load unpacked" and pick the folder. Open a new tab and it's there.

Note

The keys sit in plain text in script.js. That's fine on your own machine, but keep them out of anything you push to a public repo.

It asks for three permissions: storage for your shortcuts, tabs to open sites when you click them, and activeTab, which is optional, for screenshots. Nothing gets sent anywhere except Unsplash and your screenshot service if you set one up, and there's no tracking or analytics.

Rough edges

This is a portfolio and demo project. It works as described, but I haven't published it on the Chrome Web Store, so you're installing it unpacked.

Heads up

Unsplash's free tier allows 50 requests an hour. With a new photo every half hour you won't get near that, but if you start hammering reloads while tinkering, that's the limit you'll hit.

Screenshots will fail on some sites because of CORS or because they block iframe embedding. That's normal, and the favicon fallback catches it. If backgrounds stop loading, check the key first, then the browser console.

If you care about keeping your browser tidy, this pairs well with a short, disciplined bookmarks bar. And for telling your profiles apart before you even open a tab, there's Browser Profile Icons.