Skip to content

Commit 7bd9931

Browse files
Expose legal pages in footer
Add root-level privacy and terms routes, reuse the existing legal document renderer, and update public legal links.
1 parent a002f70 commit 7bd9931

9 files changed

Lines changed: 153 additions & 69 deletions

File tree

apps/web/content/legal/terms.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ You may opt out of marketing communications at any time by clicking the "unsubsc
7474

7575
## 9. Privacy and Third-Party Services
7676

77-
Your use of the Service is also governed by our [Privacy Policy](/legal/privacy). Please review it to understand our practices.
77+
Your use of the Service is also governed by our [Privacy Policy](/privacy). Please review it to understand our practices.
7878

7979
The Service may integrate with third-party services to provide certain features, including cloud-based transcription, AI-powered summarization, payment processing, and analytics. When you enable cloud-based features, your data may be processed by our sub-processors. You acknowledge and agree that your use of these features is subject to the terms and privacy practices of such third-party services.
8080

apps/web/netlify.toml

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ force = true
6666

6767
[[redirects]]
6868
from = "https://hyprnote.com/legal/*"
69-
to = "https://char.com/legal/:splat"
69+
to = "https://anarlog.so/:splat"
7070
status = 301
7171
force = true
7272

@@ -203,7 +203,7 @@ status = 301
203203
force = true
204204

205205
# Domain migration: char.com -> anarlog.so (301 for SEO)
206-
# Char is shut down except for /blog/* and /legal/* which redirect to anarlog.so
206+
# Char is shut down except for /blog/* and root legal pages which redirect to anarlog.so
207207

208208
[[redirects]]
209209
from = "https://char.com/blog/*"
@@ -217,14 +217,44 @@ to = "https://anarlog.so/blog/:splat"
217217
status = 301
218218
force = true
219219

220+
[[redirects]]
221+
from = "/legal/*"
222+
to = "/:splat"
223+
status = 301
224+
force = true
225+
220226
[[redirects]]
221227
from = "https://char.com/legal/*"
222-
to = "https://anarlog.so/legal/:splat"
228+
to = "https://anarlog.so/:splat"
223229
status = 301
224230
force = true
225231

226232
[[redirects]]
227233
from = "https://www.char.com/legal/*"
228-
to = "https://anarlog.so/legal/:splat"
234+
to = "https://anarlog.so/:splat"
235+
status = 301
236+
force = true
237+
238+
[[redirects]]
239+
from = "https://char.com/privacy"
240+
to = "https://anarlog.so/privacy"
241+
status = 301
242+
force = true
243+
244+
[[redirects]]
245+
from = "https://www.char.com/privacy"
246+
to = "https://anarlog.so/privacy"
247+
status = 301
248+
force = true
249+
250+
[[redirects]]
251+
from = "https://char.com/terms"
252+
to = "https://anarlog.so/terms"
253+
status = 301
254+
force = true
255+
256+
[[redirects]]
257+
from = "https://www.char.com/terms"
258+
to = "https://anarlog.so/terms"
229259
status = 301
230260
force = true

apps/web/public/robots.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ Allow: /docs
2424
Allow: /changelog
2525
Allow: /pricing
2626
Allow: /enterprise
27-
Allow: /legal/
27+
Allow: /privacy
28+
Allow: /terms
2829
Allow: /download
2930
Allow: /faq
3031
Allow: /about

apps/web/src/routes/legal/$slug.tsx renamed to apps/web/src/components/legal-document.tsx

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,27 @@
11
import { MDXContent } from "@content-collections/mdx/react";
2-
import { createFileRoute, Link, notFound } from "@tanstack/react-router";
3-
import { allLegals } from "content-collections";
2+
import { Link } from "@tanstack/react-router";
3+
import type { Legal } from "content-collections";
44

5-
import { mdxComponents } from "@/components/mdx-components";
65
import { ANARLOG_SITE_URL } from "@/lib/seo";
76

8-
export const Route = createFileRoute("/legal/$slug")({
9-
component: Component,
10-
loader: async ({ params }) => {
11-
const doc = allLegals.find((d) => d.slug === params.slug);
12-
if (!doc) {
13-
throw notFound();
14-
}
15-
return { doc };
16-
},
17-
head: ({ loaderData }) => {
18-
const doc = loaderData?.doc;
19-
if (!doc) return {};
20-
const url = `${ANARLOG_SITE_URL}/legal/${doc.slug}`;
21-
return {
22-
links: [{ rel: "canonical", href: url }],
23-
meta: [
24-
{ title: `${doc.title} — Anarlog` },
25-
{ name: "description", content: doc.summary || doc.title },
26-
{ property: "og:title", content: doc.title },
27-
{ property: "og:description", content: doc.summary || doc.title },
28-
{ property: "og:url", content: url },
29-
],
30-
};
31-
},
32-
});
7+
import { mdxComponents } from "./mdx-components";
338

34-
function Component() {
35-
const { doc } = Route.useLoaderData();
9+
export function legalHead(doc: Legal, path: "/privacy" | "/terms") {
10+
const url = `${ANARLOG_SITE_URL}${path}`;
3611

12+
return {
13+
links: [{ rel: "canonical", href: url }],
14+
meta: [
15+
{ title: `${doc.title} — Anarlog` },
16+
{ name: "description", content: doc.summary || doc.title },
17+
{ property: "og:title", content: doc.title },
18+
{ property: "og:description", content: doc.summary || doc.title },
19+
{ property: "og:url", content: url },
20+
],
21+
};
22+
}
23+
24+
export function LegalDocument({ doc }: { doc: Legal }) {
3725
return (
3826
<main className="mx-auto max-w-3xl px-6 py-16">
3927
<Link

apps/web/src/components/site-footer.tsx

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,10 @@ export function SiteFooter() {
1717
<Link to="/changelog/" className="hover:text-[#181613]">
1818
Changelog
1919
</Link>
20-
<Link
21-
to="/legal/$slug/"
22-
params={{ slug: "privacy" }}
23-
className="hover:text-[#181613]"
24-
>
20+
<Link to="/privacy/" className="hover:text-[#181613]">
2521
Privacy
2622
</Link>
27-
<Link
28-
to="/legal/$slug/"
29-
params={{ slug: "terms" }}
30-
className="hover:text-[#181613]"
31-
>
23+
<Link to="/terms/" className="hover:text-[#181613]">
3224
Terms
3325
</Link>
3426
</nav>

apps/web/src/routeTree.gen.ts

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@
1010

1111
import { Route as rootRouteImport } from './routes/__root'
1212
import { Route as UpdatePasswordRouteImport } from './routes/update-password'
13+
import { Route as TermsRouteImport } from './routes/terms'
1314
import { Route as ResetPasswordRouteImport } from './routes/reset-password'
15+
import { Route as PrivacyRouteImport } from './routes/privacy'
1416
import { Route as FoundersRouteImport } from './routes/founders'
1517
import { Route as AuthRouteImport } from './routes/auth'
1618
import { Route as ViewRouteRouteImport } from './routes/_view/route'
1719
import { Route as IndexRouteImport } from './routes/index'
1820
import { Route as ChangelogIndexRouteImport } from './routes/changelog/index'
1921
import { Route as BlogIndexRouteImport } from './routes/blog/index'
20-
import { Route as LegalSlugRouteImport } from './routes/legal/$slug'
2122
import { Route as ChangelogVersionRouteImport } from './routes/changelog/$version'
2223
import { Route as BlogSlugRouteImport } from './routes/blog/$slug'
2324
import { Route as ApiTemplatesRouteImport } from './routes/api/templates'
@@ -80,11 +81,21 @@ const UpdatePasswordRoute = UpdatePasswordRouteImport.update({
8081
path: '/update-password',
8182
getParentRoute: () => rootRouteImport,
8283
} as any)
84+
const TermsRoute = TermsRouteImport.update({
85+
id: '/terms',
86+
path: '/terms',
87+
getParentRoute: () => rootRouteImport,
88+
} as any)
8389
const ResetPasswordRoute = ResetPasswordRouteImport.update({
8490
id: '/reset-password',
8591
path: '/reset-password',
8692
getParentRoute: () => rootRouteImport,
8793
} as any)
94+
const PrivacyRoute = PrivacyRouteImport.update({
95+
id: '/privacy',
96+
path: '/privacy',
97+
getParentRoute: () => rootRouteImport,
98+
} as any)
8899
const FoundersRoute = FoundersRouteImport.update({
89100
id: '/founders',
90101
path: '/founders',
@@ -114,11 +125,6 @@ const BlogIndexRoute = BlogIndexRouteImport.update({
114125
path: '/blog/',
115126
getParentRoute: () => rootRouteImport,
116127
} as any)
117-
const LegalSlugRoute = LegalSlugRouteImport.update({
118-
id: '/legal/$slug',
119-
path: '/legal/$slug',
120-
getParentRoute: () => rootRouteImport,
121-
} as any)
122128
const ChangelogVersionRoute = ChangelogVersionRouteImport.update({
123129
id: '/changelog/$version',
124130
path: '/changelog/$version',
@@ -412,7 +418,9 @@ export interface FileRoutesByFullPath {
412418
'/': typeof IndexRoute
413419
'/auth': typeof AuthRoute
414420
'/founders': typeof FoundersRoute
421+
'/privacy': typeof PrivacyRoute
415422
'/reset-password': typeof ResetPasswordRoute
423+
'/terms': typeof TermsRoute
416424
'/update-password': typeof UpdatePasswordRoute
417425
'/app': typeof ViewAppRouteRouteWithChildren
418426
'/pricing': typeof ViewPricingRoute
@@ -421,7 +429,6 @@ export interface FileRoutesByFullPath {
421429
'/api/templates': typeof ApiTemplatesRoute
422430
'/blog/$slug': typeof BlogSlugRoute
423431
'/changelog/$version': typeof ChangelogVersionRoute
424-
'/legal/$slug': typeof LegalSlugRoute
425432
'/blog/': typeof BlogIndexRoute
426433
'/changelog/': typeof ChangelogIndexRoute
427434
'/app/account': typeof ViewAppAccountRoute
@@ -478,15 +485,16 @@ export interface FileRoutesByTo {
478485
'/': typeof IndexRoute
479486
'/auth': typeof AuthRoute
480487
'/founders': typeof FoundersRoute
488+
'/privacy': typeof PrivacyRoute
481489
'/reset-password': typeof ResetPasswordRoute
490+
'/terms': typeof TermsRoute
482491
'/update-password': typeof UpdatePasswordRoute
483492
'/pricing': typeof ViewPricingRoute
484493
'/api/media-upload': typeof ApiMediaUploadRoute
485494
'/api/shortcuts': typeof ApiShortcutsRoute
486495
'/api/templates': typeof ApiTemplatesRoute
487496
'/blog/$slug': typeof BlogSlugRoute
488497
'/changelog/$version': typeof ChangelogVersionRoute
489-
'/legal/$slug': typeof LegalSlugRoute
490498
'/blog': typeof BlogIndexRoute
491499
'/changelog': typeof ChangelogIndexRoute
492500
'/app/account': typeof ViewAppAccountRoute
@@ -545,7 +553,9 @@ export interface FileRoutesById {
545553
'/_view': typeof ViewRouteRouteWithChildren
546554
'/auth': typeof AuthRoute
547555
'/founders': typeof FoundersRoute
556+
'/privacy': typeof PrivacyRoute
548557
'/reset-password': typeof ResetPasswordRoute
558+
'/terms': typeof TermsRoute
549559
'/update-password': typeof UpdatePasswordRoute
550560
'/_view/app': typeof ViewAppRouteRouteWithChildren
551561
'/_view/pricing': typeof ViewPricingRoute
@@ -554,7 +564,6 @@ export interface FileRoutesById {
554564
'/api/templates': typeof ApiTemplatesRoute
555565
'/blog/$slug': typeof BlogSlugRoute
556566
'/changelog/$version': typeof ChangelogVersionRoute
557-
'/legal/$slug': typeof LegalSlugRoute
558567
'/blog/': typeof BlogIndexRoute
559568
'/changelog/': typeof ChangelogIndexRoute
560569
'/_view/app/account': typeof ViewAppAccountRoute
@@ -613,7 +622,9 @@ export interface FileRouteTypes {
613622
| '/'
614623
| '/auth'
615624
| '/founders'
625+
| '/privacy'
616626
| '/reset-password'
627+
| '/terms'
617628
| '/update-password'
618629
| '/app'
619630
| '/pricing'
@@ -622,7 +633,6 @@ export interface FileRouteTypes {
622633
| '/api/templates'
623634
| '/blog/$slug'
624635
| '/changelog/$version'
625-
| '/legal/$slug'
626636
| '/blog/'
627637
| '/changelog/'
628638
| '/app/account'
@@ -679,15 +689,16 @@ export interface FileRouteTypes {
679689
| '/'
680690
| '/auth'
681691
| '/founders'
692+
| '/privacy'
682693
| '/reset-password'
694+
| '/terms'
683695
| '/update-password'
684696
| '/pricing'
685697
| '/api/media-upload'
686698
| '/api/shortcuts'
687699
| '/api/templates'
688700
| '/blog/$slug'
689701
| '/changelog/$version'
690-
| '/legal/$slug'
691702
| '/blog'
692703
| '/changelog'
693704
| '/app/account'
@@ -745,7 +756,9 @@ export interface FileRouteTypes {
745756
| '/_view'
746757
| '/auth'
747758
| '/founders'
759+
| '/privacy'
748760
| '/reset-password'
761+
| '/terms'
749762
| '/update-password'
750763
| '/_view/app'
751764
| '/_view/pricing'
@@ -754,7 +767,6 @@ export interface FileRouteTypes {
754767
| '/api/templates'
755768
| '/blog/$slug'
756769
| '/changelog/$version'
757-
| '/legal/$slug'
758770
| '/blog/'
759771
| '/changelog/'
760772
| '/_view/app/account'
@@ -813,14 +825,15 @@ export interface RootRouteChildren {
813825
ViewRouteRoute: typeof ViewRouteRouteWithChildren
814826
AuthRoute: typeof AuthRoute
815827
FoundersRoute: typeof FoundersRoute
828+
PrivacyRoute: typeof PrivacyRoute
816829
ResetPasswordRoute: typeof ResetPasswordRoute
830+
TermsRoute: typeof TermsRoute
817831
UpdatePasswordRoute: typeof UpdatePasswordRoute
818832
ApiMediaUploadRoute: typeof ApiMediaUploadRoute
819833
ApiShortcutsRoute: typeof ApiShortcutsRoute
820834
ApiTemplatesRoute: typeof ApiTemplatesRoute
821835
BlogSlugRoute: typeof BlogSlugRoute
822836
ChangelogVersionRoute: typeof ChangelogVersionRoute
823-
LegalSlugRoute: typeof LegalSlugRoute
824837
BlogIndexRoute: typeof BlogIndexRoute
825838
ChangelogIndexRoute: typeof ChangelogIndexRoute
826839
ApiAssetsSplatRoute: typeof ApiAssetsSplatRoute
@@ -867,13 +880,27 @@ declare module '@tanstack/react-router' {
867880
preLoaderRoute: typeof UpdatePasswordRouteImport
868881
parentRoute: typeof rootRouteImport
869882
}
883+
'/terms': {
884+
id: '/terms'
885+
path: '/terms'
886+
fullPath: '/terms'
887+
preLoaderRoute: typeof TermsRouteImport
888+
parentRoute: typeof rootRouteImport
889+
}
870890
'/reset-password': {
871891
id: '/reset-password'
872892
path: '/reset-password'
873893
fullPath: '/reset-password'
874894
preLoaderRoute: typeof ResetPasswordRouteImport
875895
parentRoute: typeof rootRouteImport
876896
}
897+
'/privacy': {
898+
id: '/privacy'
899+
path: '/privacy'
900+
fullPath: '/privacy'
901+
preLoaderRoute: typeof PrivacyRouteImport
902+
parentRoute: typeof rootRouteImport
903+
}
877904
'/founders': {
878905
id: '/founders'
879906
path: '/founders'
@@ -916,13 +943,6 @@ declare module '@tanstack/react-router' {
916943
preLoaderRoute: typeof BlogIndexRouteImport
917944
parentRoute: typeof rootRouteImport
918945
}
919-
'/legal/$slug': {
920-
id: '/legal/$slug'
921-
path: '/legal/$slug'
922-
fullPath: '/legal/$slug'
923-
preLoaderRoute: typeof LegalSlugRouteImport
924-
parentRoute: typeof rootRouteImport
925-
}
926946
'/changelog/$version': {
927947
id: '/changelog/$version'
928948
path: '/changelog/$version'
@@ -1379,14 +1399,15 @@ const rootRouteChildren: RootRouteChildren = {
13791399
ViewRouteRoute: ViewRouteRouteWithChildren,
13801400
AuthRoute: AuthRoute,
13811401
FoundersRoute: FoundersRoute,
1402+
PrivacyRoute: PrivacyRoute,
13821403
ResetPasswordRoute: ResetPasswordRoute,
1404+
TermsRoute: TermsRoute,
13831405
UpdatePasswordRoute: UpdatePasswordRoute,
13841406
ApiMediaUploadRoute: ApiMediaUploadRoute,
13851407
ApiShortcutsRoute: ApiShortcutsRoute,
13861408
ApiTemplatesRoute: ApiTemplatesRoute,
13871409
BlogSlugRoute: BlogSlugRoute,
13881410
ChangelogVersionRoute: ChangelogVersionRoute,
1389-
LegalSlugRoute: LegalSlugRoute,
13901411
BlogIndexRoute: BlogIndexRoute,
13911412
ChangelogIndexRoute: ChangelogIndexRoute,
13921413
ApiAssetsSplatRoute: ApiAssetsSplatRoute,

0 commit comments

Comments
 (0)