{"id":17209049,"url":"https://github.com/brentvollebregt/hit-counter","last_synced_at":"2025-05-10T21:05:01.890Z","repository":{"id":36208283,"uuid":"130636854","full_name":"brentvollebregt/hit-counter","owner":"brentvollebregt","description":"Easily count hits 📈 on a website by requesting a SVG displaying hit count 🎯 ","archived":false,"fork":false,"pushed_at":"2023-09-26T10:27:27.000Z","size":101,"stargazers_count":144,"open_issues_count":4,"forks_count":43,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-05-09T18:19:13.156Z","etag":null,"topics":["counter","view-counter","visitor-counter"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/brentvollebregt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-04-23T03:47:32.000Z","updated_at":"2025-03-24T17:59:42.000Z","dependencies_parsed_at":"2024-01-07T18:57:14.471Z","dependency_job_id":null,"html_url":"https://github.com/brentvollebregt/hit-counter","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brentvollebregt%2Fhit-counter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brentvollebregt%2Fhit-counter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brentvollebregt%2Fhit-counter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brentvollebregt%2Fhit-counter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brentvollebregt","download_url":"https://codeload.github.com/brentvollebregt/hit-counter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253300851,"owners_count":21886523,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["counter","view-counter","visitor-counter"],"created_at":"2024-10-15T02:50:39.106Z","updated_at":"2025-05-09T18:19:19.367Z","avatar_url":"https://github.com/brentvollebregt.png","language":"Python","funding_links":[],"categories":["Python","Tools"],"sub_categories":["WebTools"],"readme":"# Hit Counter\nEasily count hits on a website by requesting a SVG that displays a hit count.\n\n\u003c!-- \u003cdiv style=\"text-align: center\"\u003e\n    \u003cimg src=\"https://hitcounter.pythonanywhere.com/count/tag.svg?url=https%3A%2F%2Fgithub.com%2Fbrentvollebregt%2Fhit-counter\" alt=\"Hits\"\u003e\n\u003c/div\u003e --\u003e\n\n~~Live demo hosted at: [hitcounter.pythonanywhere.com](https://hitcounter.pythonanywhere.com/)~~\n\n\u003e ~~Please note this is only a demo instance and any traffic that causes harm to the server will be blocked.~~\n\u003e ~~Also due to how this demo instance is being hosted and the large amount of traffic it gets, the server does fall over some times.~~\n\n\u003e PythonAnywhere has understandably disabled the demo instance due to heavy disk usage.\n\n## What is This?\nThis is a server that allows a client to request for an SVG file that displays views for a URL. This URL can either be passed as a query parameter or the referrer (or referer) value in the header will be used.\n\nA small method to help prevent the count increasing after short consecutive page loads is included which uses cookies to check if the user has made the request recently.\n\n**This makes it very easy to keep track of views on static sites like Github Pages.** *It can also be used on non-static sites as a general counter.*\n\n## How Can I Use it?\n### Getting an SVG\nTo get an image for the current URL (for example is image is being requested by www.example.com), simply get the image as you normally would:\n\n```html\n\u003cimg src=\"https://hitcounter.pythonanywhere.com/count/tag.svg\" alt=\"Hits\"\u003e\n```\n\nIn this example, a hit would be added to the websites count on the server. To stop this from occurring but still get the SVG file, use:\n\n```html\n\u003cimg src=\"https://hitcounter.pythonanywhere.com/nocount/tag.svg\" alt=\"Hits\"\u003e\n```\n\n\u003e Warning: [\"*Chrome plans to radually enable strict-origin-when-cross-origin as the default policy in 85; this may impact use cases relying on the referrer value from another origin*\"](https://developers.google.com/web/updates/2020/07/referrer-policy-new-chrome-default). To get around this, you'll want to put the URL in the query string as outlined under [Getting a Count For a Site That Isn't Me](#getting-a-count-for-a-site-that-isnt-me).\n\n### Getting the Count Raw\nIf you don't want the SVG file but still want the count to use in something else, you can do a GET request to ```/count``` or as before, ```/nocount``` to not add a count. For Example:\n\n```javascript\nfetch('https://hitcounter.pythonanywhere.com/count', {\n    credentials: 'include'\n})\n    .then(res =\u003e res.text())\n    .then(count =\u003e console.log('Count: ' + count))\n```\n\n#### Using XMLHttpRequest\n\n```javascript\nlet xmlHttp = new XMLHttpRequest();\nxmlHttp.withCredentials = true;\nxmlHttp.onload = function() {\n    console.log('Count: ' + this.responseText);\n};\nxmlHttp.open('GET', 'https://hitcounter.pythonanywhere.com/count', true);\nxmlHttp.send(null);\n```\n\n#### Using Ajax\n\n```javascript\nlet targetUrl = window.location.href;\n$.ajax('https://hitcounter.pythonanywhere.com/count', {\n    data: { url: targetUrl },\n    xhrFields: { withCredentials: true }\n}).then(count =\u003e console.log('Count: ' + count));\n```\n\n\u003e Do not use `data: {url: encodeURIComponent(targetUrl)}` as Ajax will encode the string (url) for you. Doing this will encode the url twice which will then only be decoded on the server once (this can lead to broken tags in the future).\n\n### Getting a Count For a Site That Isn't Me\nThere may be circumstances that the referrer may not be sent or you may want to request an SVG or count for another site. To do this, set `url` to the URL you want to get (make sure to encoded the value).\n\nFor example, getting an SVG:\n\n```html\n\u003cimg src=\"https://hitcounter.pythonanywhere.com/nocount/tag.svg?url=www.example.com\" alt=\"Hits\"\u003e\n```\n\nAnd if you want to get the count:\n\n```javascript\nlet targetUrl = 'www.example.com';\nfetch(`https://hitcounter.pythonanywhere.com/count?url=${encodeURIComponent(targetUrl)}`, {\n    credentials: 'include'\n})\n    .then(res =\u003e res.text())\n    .then(count =\u003e console.log('Count: ' + count))\n```\n\n\u003e There are also some situations where a client will not send the Referer in the header. This is a simple solution to the server not being able to find where the request came from.\n\n## Generating Links With A Tool Hosted By The Server\nGoing to the location `/` on the server, you will be served with an HTML page that contains a tool to create the image tag or markdown element and search up a websites count.\n\n![Interface](https://nitratine.net/posts/hit-counter/interface.png)\n\n## Documentation\n- [Server Setup](./docs/setup.md)\n    - [Local Setup](./docs/setup.md#local-setup)\n    - [PythonAnywhere Setup](./docs/setup.md#pythonanywhere-setup)\n- [Server Configuration](./docs/config.md)\n- [Usage](./docs/usage.md)\n    - [Getting an SVG](./docs/usage.md#getting-an-svg)\n    - [Getting the Count Raw](./docs/usage.md#getting-the-count-raw)\n    - [Getting a Count For a Site That Isn't Me](./docs/usage.md#getting-a-count-for-a-site-that-isnt-me)\n    - [Generating Links With A Tool Hosted By The Server](./docs/usage.md#generating-links-with-a-tool-hosted-by-the-server)\n- [Background](./docs/background.md)\n    - [Anti-Refresh Counting System](./docs/background.md#anti-refresh-counting-system)\n\n## Inspiration\nThis project was inspired by [github.com/dwyl/hits](https://github.com/dwyl/hits) which is a _\"General purpose hits (page views) counter\"_ which unfortunately will only count GitHub repo views. This was my idea to expand on this and add some features with also making it compatible with any site.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrentvollebregt%2Fhit-counter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrentvollebregt%2Fhit-counter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrentvollebregt%2Fhit-counter/lists"}