Advanced Patterns
Using @graph for Multiple Schemas
Combine multiple schema types using @graph:
1<script lang="ts">
2 import { page } from '$app/state';
3 import {
4 Head,
5 SchemaOrg,
6 type SeoConfig,
7 type SchemaOrgProps,
8 } from 'svead';
9
10 const seo_config: SeoConfig = {
11 url: page.url.href,
12 title: 'Advanced Page with Multiple Schemas',
13 description: 'Example combining multiple schema types.',
14 };
15
16 // Create individual schema objects
17 const blog_posting = {
18 '@type': 'BlogPosting',
19 '@id': page.url.href,
20 headline: seo_config.title,
21 description: seo_config.description,
22 datePublished: '2023-08-22T10:00:00Z',
23 author: {
24 '@type': 'Person',
25 name: 'John Doe',
26 },
27 };
28
29 const breadcrumb_list = {
30 '@type': 'BreadcrumbList',
31 '@id': `${page.url.href}#breadcrumb`,
32 itemListElement: [
33 {
34 '@type': 'ListItem',
35 position: 1,
36 name: 'Home',
37 item: 'https://example.com',
38 },
39 {
40 '@type': 'ListItem',
41 position: 2,
42 name: seo_config.title,
43 item: page.url.href,
44 },
45 ],
46 };
47
48 // Combine using @graph
49 const schema_org_config = {
50 '@context': 'https://schema.org',
51 '@graph': [blog_posting, breadcrumb_list],
52 };
53</script>
54
55<Head {seo_config} />
56<SchemaOrg schema={schema_org_config} />Conditional Property Spreading
Use conditional spreading to include optional properties:
1<script lang="ts">
2 import { page } from '$app/state';
3 import { SchemaOrg, type SchemaOrgProps } from 'svead';
4
5 const has_image = true;
6 const open_graph_image = 'https://example.com/image.jpg';
7 const website = 'https://example.com';
8
9 const schema_org: SchemaOrgProps['schema'] = {
10 '@type': 'WebPage',
11 '@id': page.url.href,
12 name: 'Page Title',
13 // Only include image if it exists
14 ...(has_image &&
15 open_graph_image && {
16 primaryImageOfPage: {
17 '@type': 'ImageObject',
18 url: open_graph_image,
19 },
20 }),
21 // Conditionally add publisher
22 ...(website && {
23 publisher: {
24 '@type': 'Organization',
25 name: 'Example Org',
26 url: website,
27 },
28 }),
29 };
30</script>
31
32<SchemaOrg schema={schema_org} />Multiple SchemaOrg Components
You can use multiple SchemaOrg components on the same page:
1<script lang="ts">
2 import { SchemaOrg, type SchemaOrgProps } from 'svead';
3
4 const website_schema: SchemaOrgProps['schema'] = {
5 '@type': 'WebSite',
6 '@id': 'https://example.com',
7 name: 'Example Site',
8 };
9
10 const article_schema: SchemaOrgProps['schema'] = {
11 '@type': 'Article',
12 '@id': 'https://example.com/article',
13 headline: 'Article Title',
14 };
15
16 const breadcrumb_schema: SchemaOrgProps['schema'] = {
17 '@type': 'BreadcrumbList',
18 itemListElement: [/* ... */],
19 };
20</script>
21
22<SchemaOrg schema={website_schema} />
23<SchemaOrg schema={article_schema} />
24<SchemaOrg schema={breadcrumb_schema} />WebPage as Container with mainEntity
Use WebPage as a wrapper with mainEntity to indicate what the page
is primarily about:
1<script lang="ts">
2 import { page } from '$app/state';
3 import {
4 Head,
5 SchemaOrg,
6 type SeoConfig,
7 type SchemaOrgProps,
8 } from 'svead';
9
10 const seo_config: SeoConfig = {
11 url: page.url.href,
12 website: 'https://example.com',
13 title: 'My Blog Post',
14 description: 'An example blog post',
15 author_name: 'John Doe',
16 };
17
18 // WebPage wraps the main content
19 const schema_org: SchemaOrgProps['schema'] = {
20 '@type': 'WebPage',
21 '@id': page.url.href,
22 url: page.url.href,
23 name: seo_config.title,
24 description: seo_config.description,
25 isPartOf: {
26 '@type': 'WebSite',
27 '@id': seo_config.website,
28 },
29 // The page is primarily about this BlogPosting
30 mainEntity: {
31 '@type': 'BlogPosting',
32 '@id': `${page.url.href}#article`,
33 headline: seo_config.title,
34 description: seo_config.description,
35 datePublished: '2023-08-22T10:00:00Z',
36 author: {
37 '@type': 'Person',
38 name: seo_config.author_name,
39 },
40 publisher: {
41 '@type': 'Organization',
42 name: 'Example Blog',
43 },
44 mainEntityOfPage: {
45 '@type': 'WebPage',
46 '@id': page.url.href,
47 },
48 },
49 };
50</script>
51
52<Head {seo_config} />
53<SchemaOrg schema={schema_org} />This pattern is useful when you want to provide both page-level and content-level metadata in a single schema object.
Adding potentialAction for Interactivity
Use potentialAction to indicate actions users can perform on the
page:
1<script lang="ts">
2 import { page } from '$app/state';
3 import { SchemaOrg, type SchemaOrgProps } from 'svead';
4
5 const schema_org: SchemaOrgProps['schema'] = {
6 '@type': 'WebPage',
7 '@id': page.url.href,
8 url: page.url.href,
9 name: 'Article Title',
10 // Indicates this page can be read
11 potentialAction: [
12 {
13 '@type': 'ReadAction',
14 target: [page.url.href],
15 },
16 ],
17 };
18</script>
19
20<SchemaOrg schema={schema_org} />This helps with:
- Deep linking in mobile apps
- Progressive Web App integration
- Better understanding by search engines
Common action types:
ReadAction- For articles, blogs, documentationWatchAction- For video contentListenAction- For podcasts, audioSearchAction- For search functionality
1// SearchAction example for site search
2const search_action_schema = {
3 '@type': 'WebSite',
4 url: 'https://example.com',
5 potentialAction: {
6 '@type': 'SearchAction',
7 target: {
8 '@type': 'EntryPoint',
9 urlTemplate:
10 'https://example.com/search?q={search_term_string}',
11 },
12 'query-input': 'required name=search_term_string',
13 },
14};