Twitch clip datetime userscript
A userscript for displaying the actual date & time (relative to local time) of when a Twitch clip was created.
FYI: It only works on URLs that start with https://clips.twitch.tv/.
This script does not work with URLs that are on the Twitch "channel pages" (https://www.twitch.tv/CHANNEL_NAME_HERE/clip/...).
"Under the hood" the script uses Date.toLocaleString() to format the date. The format of the date & time may differ from the screenshots below.
Requirements:
- Something like the Violentmonkey extension installed for your browser.
Installation:
- Install a userscript extension (such as Violentmonkey).
- Click on this link when Violentmonkey is installed, and it will prompt you to install the userscript.
Changelog
- v0.4.0 - 2021-08-29
- Date/time placement was adjusted due to changes in the page on Twitch's end. See screenshots.
- Previously I used Tampermonkey, but later switched to Violentmonkey. During my testing, I tested with Violentmonkey and it worked fine. However, if you're currently using Tampermonkey, v0.4.0 does not work. I'm unsure as to why, but I'll try to look into it.
Screenshots:
As of v0.4.0, the timestamp shows up a bit different compared to earlier versions.
Without chat (beginning of clip)

With chat

| 1 | // ==UserScript== |
| 2 | // @name Twitch Clips - Show date & time |
| 3 | // @version 0.4.0 |
| 4 | // @description Displays the actual date & time of when a clip was created, instead of the useless "xxx days/months/weeks ago" |
| 5 | // @author Decicus |
| 6 | // @updateURL https://gist.github.com/Decicus/ec4745e680e06cfff5b1fa0a53fcff72/raw/twitch-clips-datetime.user.js |
| 7 | // @downloadURL https://gist.github.com/Decicus/ec4745e680e06cfff5b1fa0a53fcff72/raw/twitch-clips-datetime.user.js |
| 8 | // @homepageURL https://gist.github.com/Decicus/ec4745e680e06cfff5b1fa0a53fcff72 |
| 9 | // @icon https://i.alex.lol/2021-08-29_PmO4zo.png |
| 10 | // @match https://clips.twitch.tv/* |
| 11 | // @license MIT |
| 12 | // ==/UserScript== |
| 13 | |
| 14 | async function fetchClip() { |
| 15 | const slug = window.location.href.match(/https\:\/\/clips\.twitch\.tv\/([A-z0-9-_]+)/m)[1]; |
| 16 | |
| 17 | if (!slug) { |
| 18 | return; |
| 19 | } |
| 20 | |
| 21 | const response = await fetch(`https://api.twitch.tv/kraken/clips/${slug}`, { |
| 22 | headers: { |
| 23 | Accept: 'application/vnd.twitchtv.v5+json', |
| 24 | 'Client-ID': 'zs377ogpzz01ogfx26pvbddx9jodg1', |
| 25 | }, |
| 26 | }); |
| 27 | |
| 28 | const data = await response.json(); |
| 29 | |
| 30 | if (!data.created_at) { |
| 31 | return; |
| 32 | } |
| 33 | |
| 34 | const created = new Date(data.created_at); |
| 35 | const dateAndTime = created.toLocaleString(); |
| 36 | |
| 37 | const box = document.querySelector('.clips-sidebar-info'); |
| 38 | const layoutClass = box.classList[0]; |
| 39 | |
| 40 | const textElement = document.querySelector('span[class*="CoreText"]'); |
| 41 | const textClass = textElement.classList[0]; |
| 42 | |
| 43 | const element = document.createElement('div'); |
| 44 | element.className = layoutClass; |
| 45 | element.setAttribute('style', 'text-align: center; margin-top: 1em;'); |
| 46 | element.innerHTML = `<span class="${textClass}"><strong>Clip created:</strong> ${dateAndTime}</span>`; |
| 47 | |
| 48 | box.insertAdjacentElement('afterbegin', element); |
| 49 | } |
| 50 | |
| 51 | /** |
| 52 | * Observe the DOM until we find the element we're interested in. |
| 53 | * Once complete, disconnect the observer and call the `fetchClip()` function which actually inserts the |
| 54 | * timestamp into the DOM. |
| 55 | */ |
| 56 | function observerHandler(mutations, observer) |
| 57 | { |
| 58 | const textElement = document.querySelector('span[class*="CoreText"]'); |
| 59 | |
| 60 | if (!textElement) { |
| 61 | return; |
| 62 | } |
| 63 | |
| 64 | fetchClip(); |
| 65 | observer.disconnect(); |
| 66 | } |
| 67 | |
| 68 | window.addEventListener('DOMContentLoaded', function() { |
| 69 | const observer = new MutationObserver(observerHandler); |
| 70 | observer.observe(document, { |
| 71 | attributes: false, |
| 72 | childList: true, |
| 73 | characterData: false, |
| 74 | subtree: true, |
| 75 | }); |
| 76 | }); |