A free HTML clock widget you can paste anywhere

Eight lines of HTML give you a live clock that needs no service behind it. The same pattern covers a timezone board and a countdown, and none of it can be switched off by someone else.

A free HTML clock widget is eight lines, and it needs no account and no third-party script:

<div id="clock" style="font:600 32px system-ui;">--:--:--</div>

<script>
  function tick() {
    document.getElementById('clock').textContent =
      new Date().toLocaleTimeString();
  }
  tick();
  setInterval(tick, 1000);
</script>

Calling tick() once before the interval starts is the detail most snippets miss. Without it the clock shows placeholder dashes for the first second.

A live digital clock on an otherwise empty page, showing the local time.
A live digital clock on an otherwise empty page, showing the local time.

Controlling the format

toLocaleTimeString takes a locale and an options object, so you rarely need to assemble the string by hand.

<script>
  const opts = { hour: '2-digit', minute: '2-digit', hour12: false };
  const text = new Date().toLocaleTimeString('en-GB', opts);
</script>
What you want Option to pass
24 hour clock hour12: false
No seconds Omit second from the options
A fixed city timeZone: 'Asia/Seoul'
Timezone shown timeZoneName: 'short'
Date as well Use toLocaleString instead

Timezone names come from the standard database, so Europe/London, America/New_York and Asia/Seoul all work, and daylight saving is handled for you.

That last point is the reason not to calculate offsets by hand. Adding nine hours to UTC is correct for Seoul all year and wrong for London for about half of it.

Locale matters too, and it is separate from timezone. Passing 'en-GB' gives a 24 hour clock by default, 'en-US' gives 12 hour with AM and PM. Pass undefined to follow the reader's own setting.

Making the clock look like part of the page

A clock is a number that changes, which creates one specific layout problem: the digits are different widths, so the whole line jitters every second.

<style>
  #clock { font-variant-numeric: tabular-nums; }
</style>

One property fixes it. Tabular figures are equal width, so the clock stays still while the numbers change.

Two more small things worth doing. Wrap the clock in a <time> element if the value is a real timestamp, which gives it meaning beyond the visible text. And avoid animating the change, since a fading digit is harder to read than a replaced one.

For a large display clock, set the font size in clamp() rather than a fixed pixel value. The clock then fills a wall screen and still fits a phone without a media query.

A board of several timezones

This is the version that actually earns its place in an internal page, because a distributed team checking whether it is a reasonable hour somewhere is a real question.

<table id="zones">
  <tr><th>Seoul</th><td data-tz="Asia/Seoul"></td></tr>
  <tr><th>London</th><td data-tz="Europe/London"></td></tr>
  <tr><th>New York</th><td data-tz="America/New_York"></td></tr>
</table>

<script>
  function tickZones() {
    const now = new Date();
    document.querySelectorAll('[data-tz]').forEach(function (cell) {
      cell.textContent = now.toLocaleTimeString('en-GB', {
        timeZone: cell.dataset.tz,
        hour: '2-digit',
        minute: '2-digit'
      });
    });
  }
  tickZones();
  setInterval(tickZones, 1000);
</script>

Adding a city is one table row. There is no configuration file and no service to sign up to.

Two additions make this board genuinely useful rather than decorative. Print the weekday alongside the time, because the interesting question is often whether it is already tomorrow there.

And mark working hours. A cell that goes grey outside roughly nine to six answers the real question, which is whether it is reasonable to send a message right now, without the reader doing arithmetic.

A three-row table showing the current time in Seoul, London and New York.
A three-row table showing the current time in Seoul, London and New York.

A countdown, same pattern

A countdown is the same loop with subtraction in the middle.

<div id="left">--</div>

<script>
  const target = new Date('2026-12-31T23:59:59');
  function countdown() {
    const ms = target - new Date();
    if (ms <= 0) { document.getElementById('left').textContent = 'Done'; return; }
    const d = Math.floor(ms / 86400000);
    const h = Math.floor(ms / 3600000) % 24;
    const m = Math.floor(ms / 60000) % 60;
    document.getElementById('left').textContent = d + 'd ' + h + 'h ' + m + 'm';
  }
  countdown();
  setInterval(countdown, 30000);
</script>

Note the interval is 30 seconds, not one. A countdown showing days and hours does not need to be redrawn every second, and a slower interval is kinder to a phone battery.

The target date deserves a timezone. new Date('2026-12-31T23:59:59') is interpreted in the reader's local time, so a deadline set from Seoul arrives at a different moment in London.

Append an offset, or a Z for UTC, to pin it. This is the single most common bug in countdown code, and it only shows up when someone in another country looks at the page.

Your own code against an embedded widget

Both routes exist. The trade is not about difficulty, since both are a paste.

Your own script A third-party embed
Works offline Yes No
Can be switched off by someone else No Yes
Adds an external request No Yes
Styling under your control Fully Whatever the widget allows
Analytics or ads attached None Depends on the provider

For a clock, where the browser already holds the answer, there is no information the external service has that you do not. That makes the second column hard to justify.

Sharing a page that has a live clock

A clock is the clearest possible case of something a screenshot cannot carry. The image shows one moment, and it is wrong a second later.

Paste the HTML into a NOS document. It renders and runs as written, script included, at an address of its own. Share, then Share link, then Create link.

The timezone board open from a shared link, ticking in the browser.
The timezone board open from a shared link, ticking in the browser.

Everyone who opens the link sees a clock running against their own device, which is the point. Turning HTML into a link is that step by itself, and single HTML file apps covers building bigger things the same way.

If the clock renders as static text when you test it, open the file in the HTML file opener. A script kept in a neighbouring file does not travel with the page, and self-contained HTML explains how to fold it in.

Before you paste it into anything

  1. Does the element show something sensible before the first tick?
  2. Is the interval as slow as it can be for what is displayed?
  3. Is the timezone deliberate, either the reader's or a named city?
  4. Is the script inside the file rather than linked?
  5. Does it still tick when opened from the shared address?

Questions people ask

Do I need a service to put a clock on a page?

No. The browser already knows the time. A short script reading the Date object and writing into an element gives you a live clock with nothing behind it. Third-party clock embeds add a script from someone else, which can change, slow the page or stop working.

Which time does the clock show?

By default, the clock of the device viewing the page, not yours. That is usually what you want. To pin it to a particular city, pass a timeZone option to toLocaleTimeString, such as Asia/Seoul or America/New_York.

Why does my clock skip a second now and then?

Because setInterval with 1000 milliseconds drifts. The browser is not obliged to fire it exactly on time, and background tabs are throttled. For a display clock this is invisible. If it matters, tick more often, for example every 250 milliseconds, and redraw only when the second changes.

Can I put a clock into a shared page?

Yes. Paste the HTML with its script into a NOS document. It renders and runs at the document address, so anyone opening the link sees a live clock rather than a screenshot of one time.

Keep reading