Skip to content

Commit 8bc5827

Browse files
authored
Merge pull request #2983 from appwrite/fix/threads-jsonld-html-script-escape
Fix/threads jsonld html script escape
2 parents 0fbf941 + 15b420a commit 8bc5827

3 files changed

Lines changed: 45 additions & 10 deletions

File tree

src/lib/utils/metadata.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,21 @@ export function buildOpenGraphImage(title: string, description: string): string
1313
)}&subtitle=${encodeURIComponent(description)}`;
1414
}
1515

16+
/**
17+
* Escapes `<` as the JSON unicode escape `\u003c` so the result can be embedded
18+
* inside HTML `<script>` tags (including SvelteKit route data) without `</script>`
19+
* or similar sequences in string values ending the script early. `JSON.parse`
20+
* still yields the original `<`.
21+
*/
22+
export function escapeJsonLtForHtmlScript(json: string): string {
23+
return json.replace(/</g, '\\u003c');
24+
}
25+
1626
/**
1727
* Returns an inlined JSON-LD script tag without breaking IDE formatting.
18-
*
19-
* Escapes `<` as `\u003c` so content like `</script>` inside string values
20-
* (e.g. code samples in forum posts) cannot prematurely close the script element
21-
* in HTML; JSON.parse still yields the original `<`.
2228
*/
2329
export function getInlinedScriptTag(jsonSchema: string): string {
24-
const safeForInlineScript = jsonSchema.replace(/</g, '\\u003c');
30+
const safeForInlineScript = escapeJsonLtForHtmlScript(jsonSchema);
2531
return `<script type="application/ld+json">${safeForInlineScript}</` + 'script>';
2632
}
2733

@@ -43,7 +49,7 @@ export function organizationJsonSchema() {
4349
legalName: 'Appwrite Code Ltd.',
4450
description:
4551
'A secure open-source backend server provides the core APIs required to build web and mobile applications. Appwrite provides authentication, database, storage, functions, messaging, and advanced realtime capabilities.',
46-
logo: 'https://appwrite.io/assets/logotype/white.avif'
52+
logo: 'https://appwrite.io/assets/logotype/white.png'
4753
});
4854
}
4955

@@ -246,5 +252,5 @@ export function createDiscussionForumPageSchema(options: {
246252
mainEntity
247253
};
248254

249-
return JSON.stringify(graph);
255+
return escapeJsonLtForHtmlScript(JSON.stringify(graph));
250256
}

src/routes/(marketing)/+page.svelte

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
<script lang="ts">
2-
import { browser } from '$app/environment';
2+
import { browser, building } from '$app/environment';
3+
import { page } from '$app/state';
4+
import {
5+
DEFAULT_HERO_CTA,
6+
DEFAULT_HERO_SUBTITLE,
7+
DEFAULT_HERO_TITLE
8+
} from '$lib/statsig/constants';
9+
import { resolveHeroQueryOverrides } from '$lib/statsig/hero-query-overrides';
10+
import type { HeroLayoutVariant } from '$lib/statsig/hero-layout';
11+
import type { PageData } from './$types';
312
import Bento from './(components)/bento/bento.svelte';
413
import CaseStudies from './(components)/case-studies.svelte';
514
import Features from './(components)/features.svelte';
@@ -14,10 +23,30 @@
1423
import { FooterNav, MainFooter } from '$lib/components';
1524
import LogoList from './(components)/logo-list.svelte';
1625
import Ai from './(components)/ai.svelte';
26+
27+
/** Same baseline + query resolution as `hero.svelte`; tab title prefixes the brand. */
28+
type MarketingHeroPageData = PageData & {
29+
statsigBootstrap?: string | null;
30+
statsigStableUserId?: string | null;
31+
statsigUserAgent?: string | null;
32+
};
33+
34+
const data = $derived(page.data as MarketingHeroPageData);
35+
36+
const heroPageTitle = $derived(
37+
resolveHeroQueryOverrides(building ? new URLSearchParams() : page.url.searchParams, {
38+
heroLayout: (data.heroLayout ?? 0) as HeroLayoutVariant,
39+
heroSubtitle: data.heroSubtitle ?? DEFAULT_HERO_SUBTITLE,
40+
heroTitle: data.heroTitle ?? DEFAULT_HERO_TITLE,
41+
heroCta: data.heroCta ?? DEFAULT_HERO_CTA
42+
}).heroTitle
43+
);
44+
45+
const homepageDocumentTitle = $derived(`Appwrite - ${heroPageTitle}`);
1746
</script>
1847

1948
<Head
20-
title="Appwrite - Build like a team of hundreds"
49+
title={homepageDocumentTitle}
2150
description="Build like a team of hundreds with Appwrite's all-in-one, open-source infrastructure. Launch in minutes, use any framework, and scale affordably with Auth, Database, Storage, Functions, Realtime, Messaging, and Sites for static sites, SSR, and CSR frontends."
2251
/>
2352

src/routes/threads/[id]/+page.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@
138138
display: grid;
139139
grid-template-columns: 1fr auto;
140140
gap: 4rem;
141-
align-items: center;
141+
align-items: start;
142142
143143
margin-block-start: 2.5rem;
144144
}

0 commit comments

Comments
 (0)