-
-
Notifications
You must be signed in to change notification settings - Fork 13
V0.9.5 #78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
V0.9.5 #78
Changes from all commits
1f49920
5fb305f
73c83fb
aa5f9c1
b034256
f220b62
80b6845
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| dist/*.map | ||
| LICENSE.md.save | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| import { NextResponse } from 'next/server' | ||
| import { siteBaseUrl, siteInfo, siteWhatWeDo, siteHowToUse } from '@/lib/site' | ||
|
|
||
| /** Prerender at build time so /llms.txt is static like sitemap and robots. */ | ||
| export const dynamic = 'force-static' | ||
|
|
||
| /** | ||
| * Serves llms.txt at /llms.txt (via rewrite in next.config). | ||
| * Follows the llms.txt specification for AI/LLM discovery. | ||
| * Content-Type: text/plain; charset=utf-8 | ||
| */ | ||
| export async function GET() { | ||
| const body = [ | ||
| `# ${siteInfo.name}`, | ||
| '', | ||
| `> ${siteInfo.description}`, | ||
| '', | ||
| '## What We Do', | ||
| '', | ||
| ...siteWhatWeDo.map((line) => `- ${line}`), | ||
| '', | ||
| '## How To Use', | ||
| '', | ||
| 'Install the library:', | ||
| `\`\`\`\n${siteHowToUse.install}\n\`\`\``, | ||
| '', | ||
| 'Basic usage in JavaScript/TypeScript:', | ||
| `\`\`\`\n${siteHowToUse.usage}\n\`\`\``, | ||
| '', | ||
| siteHowToUse.docs, | ||
| '', | ||
| '## Services', | ||
| '', | ||
| `- [Live Demo](${siteBaseUrl}/demo): Interactive browser fingerprinting demo`, | ||
| `- [Roadmap](${siteBaseUrl}/roadmap): Product roadmap and planned features`, | ||
| `- [Home](${siteBaseUrl}): Overview and installation guide`, | ||
| '', | ||
| '## Key Information', | ||
| '', | ||
| `- [NPM Package](${siteInfo.npm}): Install fingerprint-oss from npm`, | ||
| `- [Source Code](${siteInfo.repository}): GitHub repository`, | ||
| `- [Organization](${siteInfo.organizationUrl}): ${siteInfo.organization}`, | ||
| '', | ||
| '## AI Discovery Files', | ||
| '', | ||
| `- [Sitemap](${siteBaseUrl}/sitemap.xml): Site structure`, | ||
| `- [Robots](${siteBaseUrl}/robots.txt): Crawler directives`, | ||
| '', | ||
| '## Contact', | ||
| '', | ||
| `- Organization: ${siteInfo.organization}`, | ||
| `- Website: ${siteInfo.organizationUrl}`, | ||
| `- Repository: ${siteInfo.repository}`, | ||
| ].join('\n') | ||
|
|
||
| return new NextResponse(body, { | ||
| status: 200, | ||
| headers: { | ||
| 'Content-Type': 'text/plain; charset=utf-8', | ||
| }, | ||
| }) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,34 +1,18 @@ | ||
| import { MetadataRoute } from 'next' | ||
| import type { MetadataRoute } from 'next' | ||
| import { siteBaseUrl, siteRoutes } from '@/lib/site' | ||
|
|
||
| /** | ||
| * Build the sitemap for the site. | ||
| * | ||
| * Returns a sitemap array containing three entries: the site root and two fragment anchors (`#demo`, `#installation`). | ||
| * Each entry includes `url`, `lastModified` (set to the time the function runs), `changeFrequency`, and `priority`. | ||
| * Build the sitemap for the site from the shared route config. | ||
| * Add or remove routes in `lib/site.ts` to update the sitemap automatically. | ||
| * | ||
| * @returns The generated MetadataRoute.Sitemap for the site. | ||
| */ | ||
| export default function sitemap(): MetadataRoute.Sitemap { | ||
| const baseUrl = 'https://fingerprint-oss.gossorg.in' | ||
|
|
||
| return [ | ||
| { | ||
| url: baseUrl, | ||
| lastModified: new Date(), | ||
| changeFrequency: 'weekly', | ||
| priority: 1, | ||
| }, | ||
| { | ||
| url: `${baseUrl}/#demo`, | ||
| lastModified: new Date(), | ||
| changeFrequency: 'weekly', | ||
| priority: 0.8, | ||
| }, | ||
| { | ||
| url: `${baseUrl}/#installation`, | ||
| lastModified: new Date(), | ||
| changeFrequency: 'monthly', | ||
| priority: 0.6, | ||
| } | ||
| ] | ||
| } | ||
| const now = new Date() | ||
| return siteRoutes.map((route) => ({ | ||
| url: `${siteBaseUrl}${route.path === '/' ? '' : route.path}`, | ||
| lastModified: now, | ||
| changeFrequency: route.changeFrequency ?? 'weekly', | ||
| priority: route.priority ?? 0.7, | ||
| })) | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,49 @@ | ||||||||||||||
| import type { MetadataRoute } from 'next' | ||||||||||||||
|
|
||||||||||||||
| /** Base URL for the site (no trailing slash). */ | ||||||||||||||
| export const siteBaseUrl = process.env.NEXT_PUBLIC_SITE_URL ?? 'https://fingerprint-oss.gossorg.in' | ||||||||||||||
|
Comment on lines
+3
to
+4
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Strip trailing slash from The comment documents the "no trailing slash" contract, but nothing enforces it. If 🛡️ Proposed fix-export const siteBaseUrl = process.env.NEXT_PUBLIC_SITE_URL ?? 'https://fingerprint-oss.gossorg.in'
+export const siteBaseUrl = (
+ process.env.NEXT_PUBLIC_SITE_URL ?? 'https://fingerprint-oss.gossorg.in'
+).replace(/\/$/, '')📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Public routes included in the sitemap. | ||||||||||||||
| * Add new pages here to have them appear in the sitemap automatically. | ||||||||||||||
| */ | ||||||||||||||
| export const siteRoutes: Array<{ | ||||||||||||||
| path: string | ||||||||||||||
| changeFrequency?: MetadataRoute.Sitemap[number]['changeFrequency'] | ||||||||||||||
| priority?: number | ||||||||||||||
| }> = [ | ||||||||||||||
| { path: '/', changeFrequency: 'weekly', priority: 1 }, | ||||||||||||||
| { path: '/demo', changeFrequency: 'weekly', priority: 0.9 }, | ||||||||||||||
| { path: '/roadmap', changeFrequency: 'monthly', priority: 0.8 }, | ||||||||||||||
| ] | ||||||||||||||
|
|
||||||||||||||
| /** Site name and short description for llms.txt and metadata. */ | ||||||||||||||
| export const siteInfo = { | ||||||||||||||
| name: 'Fingerprint OSS Demo', | ||||||||||||||
| description: | ||||||||||||||
| 'Free, open-source browser fingerprinting library for identifying unique visitors. Device detection, geolocation, VPN detection, and visitor analytics.', | ||||||||||||||
| repository: 'https://github.com/IntegerAlex/fingerprint-oss', | ||||||||||||||
| npm: 'https://www.npmjs.com/package/fingerprint-oss', | ||||||||||||||
| organization: 'Global Open Source Softwares (GOSS)', | ||||||||||||||
| organizationUrl: 'https://gossorg.in', | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /** What fingerprint-oss does: features and use cases for llms.txt. */ | ||||||||||||||
| export const siteWhatWeDo = [ | ||||||||||||||
| 'Browser fingerprinting: generate a stable visitor ID from device and browser signals.', | ||||||||||||||
| 'Device detection: device type, OS, browser, screen resolution, and hardware hints.', | ||||||||||||||
| 'Geolocation: approximate location (country/region) from IP when permitted.', | ||||||||||||||
| 'VPN and proxy detection: flag likely VPN or proxy usage for fraud or analytics.', | ||||||||||||||
| 'Canvas and WebGL fingerprinting: additional signals for uniqueness and bot detection.', | ||||||||||||||
| 'Privacy-focused: runs client-side; no PII required; configurable transparency and data retention.', | ||||||||||||||
| 'Use cases: fraud prevention, analytics, A/B testing, rate limiting, and anonymous visitor identification.', | ||||||||||||||
| ] | ||||||||||||||
|
|
||||||||||||||
| /** How to use fingerprint-oss: install and basic API for llms.txt. */ | ||||||||||||||
| export const siteHowToUse = { | ||||||||||||||
| install: 'npm install fingerprint-oss@latest', | ||||||||||||||
| usage: `import userInfo from 'fingerprint-oss'; | ||||||||||||||
| const data = await userInfo({ transparency: true }); | ||||||||||||||
| // data: visitorId, device, location, vpn, canvas, webgl, etc.`, | ||||||||||||||
| docs: 'Full API and options: see the Live Demo and Installation Guide on the site.', | ||||||||||||||
| } | ||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conflicting
Cache-Controlheaders for direct/api/llmsaccess.The global
/api/(.*)headers rule innext.config.mjs(lines 68–75) setsCache-Control: no-store, must-revalidatefor all API routes. The route handler here also setsCache-Control: public, max-age=3600, s-maxage=3600. When/api/llmsis accessed directly (bypassing the/llms.txtrewrite), both headers land on the same response — which is RFC-noncompliant and produces unpredictable CDN/browser behavior. The/llms.txt→/api/llmsrewrite path is unaffected since/llms.txtnever matches the/api/(.*)pattern.To fix, add an exception rule before the general
no-storeAPI rule innext.config.mjs:🛠️ Proposed fix in
next.config.mjsThen remove the explicit
Cache-Controlfrom the handler to avoid the double-set entirely:return new NextResponse(body, { status: 200, headers: { 'Content-Type': 'text/plain; charset=utf-8', - 'Cache-Control': 'public, max-age=3600, s-maxage=3600', }, })📝 Committable suggestion
🤖 Prompt for AI Agents