diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..36ab122 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 rowkav09 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 1ed0e68..5bdebbe 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,25 @@ # GitHub Profile Stats +> 🚀 Free, open-source GitHub stats card generator — embed beautiful, real-time stats in your profile README with a single line of Markdown. No tokens needed. + Beautiful, dynamically generated stats cards for your GitHub profile README. Just paste one line and your stats are always up to date — no setup, no tokens, no deployment needed. **[ghstats.dev](https://ghstats.dev)** [](https://github.com/rowkav09/GitHub-profile-stats) +## Why GitHub Profile Stats? + +- ✅ **Free & open source** — no cost, no hidden limits, MIT licensed +- 🔑 **No GitHub token required** — just your username +- 📊 **13 live stats** — stars, commits, PRs, issues, streak, weekly activity, and more +- 🎨 **12 built-in themes** — Default, Tokyo Night, Dracula, Nord, and more +- 🖼️ **SVG output** — crisp at any size, works everywhere Markdown or HTML images are supported +- ⚡ **Edge-cached** — fast responses refreshed every 30 minutes +- 🛠️ **Fully customisable** — override colours, hide stats, change border radius +- 🌍 **Works anywhere** — GitHub, GitLab, Notion, any Markdown-supported platform + ## How to Use ### 1. Create your profile README (if you don't have one) @@ -143,6 +156,35 @@ Add them to your own README:  ``` +## FAQ + +**How do I add stats to my GitHub profile?** +Create a public repo named after your GitHub username, add a `README.md`, and paste `` into it. Your stats card will appear on your profile instantly. + +**Do I need a GitHub token?** +No. GitHub Profile Stats uses the public GitHub GraphQL API without any token. Just provide your username. + +**How often do stats update?** +Cards are edge-cached and refresh every 30 minutes, so your stats are always near real-time. + +**Can I customize the colors?** +Yes! Use URL parameters like `bg`, `text`, `title_color`, `icon_color`, and `border_color` to override any colour, or choose from 12 built-in themes. + +**Is this free?** +Completely free and open source under the MIT license. No sign-up, no API key, no cost. + +## Contributing + +Contributions are welcome! If you have ideas for new themes, stats, or features, feel free to [open an issue](https://github.com/rowkav09/GitHub-profile-stats/issues) or submit a pull request. + +1. Fork the repo +2. Create a feature branch (`git checkout -b feat/my-feature`) +3. Commit your changes and open a PR + +## Support + +If you find this project useful, please consider giving it a ⭐ on [GitHub](https://github.com/rowkav09/GitHub-profile-stats) — it helps others discover it! + ## License MIT diff --git a/next.config.mjs b/next.config.mjs index 4678774..939edc9 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,4 +1,30 @@ /** @type {import('next').NextConfig} */ -const nextConfig = {}; +const nextConfig = { + async headers() { + return [ + { + source: "/(.*)", + headers: [ + { + key: "X-DNS-Prefetch-Control", + value: "on", + }, + { + key: "X-Frame-Options", + value: "SAMEORIGIN", + }, + { + key: "X-Content-Type-Options", + value: "nosniff", + }, + { + key: "Referrer-Policy", + value: "strict-origin-when-cross-origin", + }, + ], + }, + ]; + }, +}; export default nextConfig; diff --git a/package-lock.json b/package-lock.json index a398611..b276dac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -303,7 +303,6 @@ "integrity": "sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.2.2" @@ -490,7 +489,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -843,7 +841,6 @@ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "dev": true, "license": "MIT", - "peer": true, "bin": { "jiti": "bin/jiti.js" } @@ -945,7 +942,6 @@ "resolved": "https://registry.npmjs.org/next/-/next-14.2.35.tgz", "integrity": "sha512-KhYd2Hjt/O1/1aZVX3dCwGXM1QmOV4eNM2UTacK5gipDdPN/oHHK/4oVGy7X8GMfPMsUTUEmGlsy0EY1YGAkig==", "license": "MIT", - "peer": true, "dependencies": { "@next/env": "14.2.35", "@swc/helpers": "0.5.5", @@ -1122,7 +1118,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -1292,7 +1287,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -1305,7 +1299,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -1580,7 +1573,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, diff --git a/src/app/layout.tsx b/src/app/layout.tsx index b078952..a1766e3 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -3,14 +3,101 @@ import { Analytics } from "@vercel/analytics/next"; import "./globals.css"; export const metadata: Metadata = { - title: "GitHub Profile Stats", + metadataBase: new URL("https://ghstats.dev"), + title: { + default: + "GitHub Profile Stats — Beautiful Stats Cards for Your README", + template: "%s | GitHub Profile Stats", + }, description: - "Generate beautiful, embeddable GitHub stats cards for your README.", + "Generate beautiful, dynamically generated GitHub stats cards for your profile README. 13 stats, 12 themes, fully customizable SVG cards — just paste one line. No tokens, no setup, no deployment needed. Free and open source.", + keywords: [ + "github stats", + "github profile stats", + "github readme stats", + "github stats card", + "github profile readme", + "readme stats generator", + "github contribution stats", + "github streak stats", + "svg stats card", + "developer stats", + "github activity", + "open source", + "github readme generator", + "profile readme", + "github stats badge", + ], + authors: [{ name: "rowkav09", url: "https://github.com/rowkav09" }], + creator: "rowkav09", + publisher: "rowkav09", + openGraph: { + title: + "GitHub Profile Stats — Beautiful Stats Cards for Your README", + description: + "Generate beautiful, dynamically generated GitHub stats cards for your profile README. 13 stats, 12 themes, fully customizable SVG cards — just paste one line. No tokens, no setup, no deployment needed. Free and open source.", + url: "https://ghstats.dev", + siteName: "GitHub Profile Stats", + type: "website", + locale: "en_US", + images: [ + { + url: "/opengraph-image", + width: 1200, + height: 630, + alt: "GitHub Profile Stats — Beautiful Stats Cards for Your README", + }, + ], + }, + twitter: { + card: "summary_large_image", + title: + "GitHub Profile Stats — Beautiful Stats Cards for Your README", + description: + "Generate beautiful, dynamically generated GitHub stats cards for your profile README. 13 stats, 12 themes, fully customizable SVG cards — just paste one line. No tokens, no setup, no deployment needed. Free and open source.", + images: ["/opengraph-image"], + creator: "@rowkav09", + }, + alternates: { + canonical: "https://ghstats.dev", + }, + robots: { + index: true, + follow: true, + googleBot: { + index: true, + follow: true, + "max-video-preview": -1, + "max-image-preview": "large", + "max-snippet": -1, + }, + }, icons: { icon: "https://github.com/rowkav09.png", }, }; +const jsonLd = { + "@context": "https://schema.org", + "@type": "WebApplication", + name: "GitHub Profile Stats", + description: + "Generate beautiful, dynamically generated GitHub stats cards for your profile README. 13 stats, 12 themes, fully customizable SVG cards — just paste one line. No tokens, no setup, no deployment needed. Free and open source.", + url: "https://ghstats.dev", + applicationCategory: "DeveloperApplication", + operatingSystem: "All", + offers: { + "@type": "Offer", + price: "0", + priceCurrency: "USD", + }, + author: { + "@type": "Person", + name: "rowkav09", + url: "https://github.com/rowkav09", + }, +}; + export default function RootLayout({ children, }: { @@ -18,6 +105,12 @@ export default function RootLayout({ }) { return ( +
+ + {children}