Skip to content

Commit 4a50aa3

Browse files
authored
Add an "Other" type .mdx and add privacy-policy (#10)
1 parent 2d3dc41 commit 4a50aa3

File tree

6 files changed

+202
-6
lines changed

6 files changed

+202
-6
lines changed

app/[slug]/page.tsx

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import 'css/prism.css'
2+
import 'katex/dist/katex.css'
3+
4+
import { components } from '@/components/MDXComponents'
5+
import { MDXLayoutRenderer } from 'pliny/mdx-components'
6+
import { allOthers } from 'contentlayer/generated'
7+
import type { Other } from 'contentlayer/generated'
8+
import { Metadata } from 'next'
9+
import siteMetadata from '@/data/siteMetadata'
10+
import { notFound } from 'next/navigation'
11+
12+
export async function generateMetadata({
13+
params,
14+
}: {
15+
params: { slug: string }
16+
}): Promise<Metadata | undefined> {
17+
const slug = decodeURI(params.slug)
18+
const post = allOthers.find((p) => p.slug === slug)
19+
if (!post) {
20+
return
21+
}
22+
23+
const ogImages = [
24+
{
25+
url: siteMetadata.socialBanner.includes('http')
26+
? siteMetadata.socialBanner
27+
: siteMetadata.siteUrl + siteMetadata.socialBanner,
28+
},
29+
]
30+
31+
return {
32+
title: post.title,
33+
openGraph: {
34+
title: post.title,
35+
siteName: siteMetadata.title,
36+
locale: 'en_US',
37+
type: 'website',
38+
url: './',
39+
images: ogImages,
40+
},
41+
twitter: {
42+
card: 'summary_large_image',
43+
title: post.title,
44+
images: [siteMetadata.socialBanner],
45+
},
46+
}
47+
}
48+
49+
export const generateStaticParams = async () => {
50+
return allOthers.map((p) => ({ slug: p.slug }))
51+
}
52+
53+
export default async function Page({ params }: { params: { slug: string } }) {
54+
const slug = decodeURI(params.slug)
55+
const post = allOthers.find((p) => p.slug === slug) as Other
56+
57+
if (!post) {
58+
return notFound()
59+
}
60+
61+
const jsonLd = post.structuredData
62+
63+
return (
64+
<>
65+
<script
66+
type="application/ld+json"
67+
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
68+
/>
69+
<div className="mx-auto max-w-4xl px-4 py-8">
70+
<article className="prose prose-lg max-w-none dark:prose-invert">
71+
<header className="mb-8">
72+
<h1 className="text-3xl font-bold leading-tight tracking-tight text-gray-900 dark:text-gray-100 sm:text-4xl">
73+
{post.title}
74+
</h1>
75+
</header>
76+
<div className="prose-content">
77+
<MDXLayoutRenderer code={post.body.code} components={components} toc={post.toc} />
78+
</div>
79+
</article>
80+
</div>
81+
</>
82+
)
83+
}

app/sitemap.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { MetadataRoute } from 'next'
2-
import { allBlogs } from 'contentlayer/generated'
2+
import { allBlogs, allOthers } from 'contentlayer/generated'
33
import siteMetadata from '@/data/siteMetadata'
44

55
export default function sitemap(): MetadataRoute.Sitemap {
@@ -12,10 +12,15 @@ export default function sitemap(): MetadataRoute.Sitemap {
1212
lastModified: post.lastmod || post.date,
1313
}))
1414

15+
const otherRoutes = allOthers.map((post) => ({
16+
url: `${siteUrl}/${post.path}`,
17+
lastModified: new Date().toISOString().split('T')[0],
18+
}))
19+
1520
const routes = ['', 'blog', 'projects', 'tags'].map((route) => ({
1621
url: `${siteUrl}/${route}`,
1722
lastModified: new Date().toISOString().split('T')[0],
1823
}))
1924

20-
return [...routes, ...blogRoutes]
25+
return [...routes, ...blogRoutes, ...otherRoutes]
2126
}

app/tag-data.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"argot":2}
1+
{"argot":3}

components/Footer.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ const Footer = () => {
1212
</div>
1313
<div className="flex flex-col items-center gap-4 md:flex-row">
1414
<div className="flex space-x-4 text-lg font-medium ">
15-
{/* <Link className="link-underline" href="/privacy-policy">
15+
<Link className="link-underline" href="/privacy-policy">
1616
Privacy Policy
17-
</Link> */}
17+
</Link>
1818
<Link
1919
className="link-underline"
2020
href="https://github.com/argotorg/assets"

contentlayer.config.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,32 @@ export const Authors = defineDocumentType(() => ({
143143
computedFields,
144144
}))
145145

146+
export const Other = defineDocumentType(() => ({
147+
name: 'Other',
148+
filePathPattern: '*.mdx',
149+
contentType: 'mdx',
150+
fields: {
151+
title: { type: 'string', required: true },
152+
layout: { type: 'string' },
153+
canonicalUrl: { type: 'string' },
154+
},
155+
computedFields: {
156+
...computedFields,
157+
structuredData: {
158+
type: 'json',
159+
resolve: (doc) => ({
160+
'@context': 'https://schema.org',
161+
'@type': 'WebPage',
162+
headline: doc.title,
163+
url: `${siteMetadata.siteUrl}/${doc._raw.flattenedPath}`,
164+
}),
165+
},
166+
},
167+
}))
168+
146169
export default makeSource({
147170
contentDirPath: 'data',
148-
documentTypes: [Blog, Authors],
171+
documentTypes: [Blog, Authors, Other],
149172
mdx: {
150173
cwd: process.cwd(),
151174
remarkPlugins: [

data/privacy-policy.mdx

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
---
2+
title: 'Privacy Policy'
3+
layout: PostBanner
4+
---
5+
6+
**Privacy Notice for Argot**
7+
Version: 1.0
8+
9+
This privacy notice (“**Privacy Notice**”) explains how we collect, use, disclose, and protect your personal data when you use our website ([https://argot.org/](https://argot.org/), “**Website**”), our services, or otherwise interact with us. Additional information may be provided in consent forms, terms and conditions, additional privacy notices, or notices. We use the word “**data**” here interchangeably with “**personal data**”.
10+
11+
If you share personal data of others with us, you must ensure that the data is accurate and that they have been informed and have consented. Please share this Privacy Notice with them.
12+
13+
This Privacy Notice is aligned with the Federal Data Protection Act (“**FDPA**”) and the EU General Data Protection Regulation (“**GDPR**”), where applicable on a case-by-case basis.
14+
15+
### 1. Controller
16+
17+
Unless stated otherwise in a specific case, the person responsible (“**Controller**”) for processing your data under this Privacy Notice is:
18+
19+
**Argot Collective**
20+
21+
**c/o Centralis Switzerland GmbH**
22+
Bahnhofstrasse 10
23+
6300 Zug
24+
Switzerland
25+
dataprotection@argot.org
26+
27+
### 2. Data Collection and Purpose of Data Processing
28+
29+
We process the following data about you for the purposes outlined below:
30+
31+
- **Website**: When you visit our Website, we process your data to ensure its functionality and security.
32+
- **Communication**: When you contact us, we process the exchanged data to communicate with you and respond to your enquiries. By providing the data, you agree to its use as outlined in this Privacy Notice.
33+
The data collected includes: contact details; type, manner, place and time of communication; content of communication; etc.
34+
35+
### 3. Legal Basis for Data Processing
36+
37+
If we process your data based on your consent, you may withdraw it at any time with future effect by emailing us at dataprotection@argot.org. This does not affect processing carried out before the withdrawal or based on other legal grounds.
38+
39+
Where consent is not required, we process your data based on other legal bases, such as contract performance, legal obligations, vital interests, public tasks, or our legitimate interests (e.g. legal compliance, marketing, business development, or risk management).
40+
41+
### 4. Cookies and Tools
42+
43+
Our Website may use cookies, and we may allow certain third parties to do so. You can adjust your browser settings to block or delete cookies and similar technologies or use browser extensions to block third-party tracking.
44+
45+
We use the following tool(s) to ensure a tailored design and the continuous optimization of our Website:
46+
47+
- **Umami**: We use Umami offered by Umami Software, Inc. (based in the US) on our Website. Umami provides essential insights into website traffic, user behaviour, and performance, in order to analyse and optimise our Website. Umami does not collect any personally identifiable information and anonymizes all data collected. Further information can be found in the documentation of Umami Software, Inc.: [https://umami.is/docs](https://umami.is/docs).
48+
49+
### 5\. Links to Third-Party Websites
50+
51+
Our Website may contain links to third-party websites. We are not responsible for their content or data processing. Please refer to the privacy notices of those third parties.
52+
53+
### 6\. Plug-Ins and Third-Party Platforms
54+
55+
We do not use plug-ins on our Website. Icons from third parties (e.g., GitHub, X/Twitter, Farcaster) are passive links only.
56+
57+
We operate accounts on third-party platforms (e.g., GitHub, X/Twitter, Farcaster). If you interact with our accounts on these third-party platforms, your data will also be processed according to the privacy notices of the respective platform.
58+
59+
### 7\. Transfer of Data to Third Parties
60+
61+
We may share your data with third parties, including service providers acting on our behalf and under our instructions (e.g. IT, marketing, security, banking, legal, etc.), contractual partners (e.g. dealers, subcontractors, etc.), or authorities where legally required or necessary to protect our legitimate interests.
62+
63+
### 8\. Disclosure of Data Abroad
64+
65+
Your data may be transferred to, processed, or stored in countries outside the European Economic Area (EEA) or Switzerland. These countries may not offer an adequate level of data protection. We transfer data only where necessary for contract performance, legal claims, based on your consent, or with appropriate safeguards (e.g. EU-US Data Privacy Framework, Swiss-US Data Privacy Framework, or Standard Contractual Clauses, adjusted according to Swiss law).
66+
67+
### 9\. Retention and Storage of Data
68+
69+
We retain your data only as long as necessary for the purposes for which it was collected or to comply with legal obligations or defend legal claims. After the applicable retention period, your data will be securely deleted in accordance with the law.
70+
71+
### 10\. Data Security
72+
73+
We take appropriate organizational and technical security measures to protect your data from accidental loss, unauthorized access, misuse, alteration, or disclosure. However, no system is completely immune to cyber threats. Despite our best efforts, we and your data may still be exposed to cyberattacks, hacking, brute-force attempts, malware, and other malicious or fraudulent activities beyond our control. We have established procedures to respond to data breaches and will notify you and any relevant authorities when legally required.
74+
75+
### 11\. Your Rights
76+
77+
You have the right to access, rectify, delete, restrict or object to the processing of your personal data, to withdraw your consent, and to request data portability. You may also file a complaint with the competent data protection authority (Switzerland: Federal Data Protection and Information Commissioner (FDPIC), [www.edoeb.admin.ch](http://www.edoeb.admin.ch)). Before doing so, we encourage you to contact us directly at dataprotection@argot.org so we can address your concerns. We may need to verify your identity before processing your request.
78+
79+
Please note that legal obligations or overriding interests may restrict certain rights and that exercising your rights may conflict with your contractual obligations.
80+
81+
### 12\. Amendment of this Privacy Notice
82+
83+
Due to development of our Website and changes in law or regulatory requirements, this Privacy Notice might be updated from time to time. The current version can be found on our Website.
84+
85+
Last updated: 29.08.2025

0 commit comments

Comments
 (0)