mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2025-07-21 11:21:16 -04:00
55 lines
1.6 KiB
JavaScript
55 lines
1.6 KiB
JavaScript
import { h, render } from "preact";
|
|
import { useState, useEffect } from "preact/hooks";
|
|
import fetch from "unfetch";
|
|
import canonicalUrl from "get-canonical-url";
|
|
|
|
// shared react components:
|
|
import Loading from "./components/loading.js";
|
|
|
|
// API endpoint
|
|
const HITS_ENDPOINT = "/api/hits/";
|
|
|
|
const Counter = (props) => {
|
|
const [hits, setHits] = useState();
|
|
|
|
// start fetching hits from API once slug is set
|
|
useEffect(() => {
|
|
fetch(`${HITS_ENDPOINT}?slug=${encodeURIComponent(props.slug)}`)
|
|
.then((response) => response.json())
|
|
.then((data) => setHits(data.hits || 0));
|
|
}, [props.slug]);
|
|
|
|
// show spinning loading indicator if data isn't fetched yet
|
|
if (!hits) {
|
|
return <Loading boxes={3} width={20} />;
|
|
}
|
|
|
|
// we have data!
|
|
return (
|
|
<span title={`${hits.toLocaleString("en-US")} ${hits === 1 ? "view" : "views"}`}>
|
|
{hits.toLocaleString("en-US")}
|
|
</span>
|
|
);
|
|
};
|
|
|
|
// don't continue if there isn't a span#meta-hits element on this page
|
|
const wrapper = document.querySelector("div#meta-hits-counter");
|
|
|
|
// page must have both span#meta-hits and canonical URL to enter
|
|
if (typeof window !== "undefined" && wrapper) {
|
|
// use <link rel="canonical"> to deduce a consistent identifier for this page
|
|
const canonical = canonicalUrl({
|
|
normalize: true,
|
|
normalizeOptions: {
|
|
removeTrailingSlash: true,
|
|
removeQueryParameters: true,
|
|
stripHash: true,
|
|
},
|
|
});
|
|
|
|
// get path and strip beginning and ending forward slash
|
|
const slug = new URL(canonical).pathname.replace(/^\/|\/$/g, "");
|
|
|
|
render(<Counter slug={slug} />, wrapper);
|
|
}
|