add properties

This commit is contained in:
oe.kazuma 2021-07-19 23:21:07 +09:00
parent d61205a61d
commit 7b4beba197
4 changed files with 309 additions and 85 deletions

View File

@ -32,29 +32,44 @@ yarn add svelte-meta-tags
### Properties
| Property | Type | Description |
| ---------------------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------- |
| `title` | string | Sets the page meta title. |
| `description` | string | Sets the page meta description. |
| `robots` | string (default index,follow) | Sets the page meta robots. |
| `keywords` | string | Set the page keywords. |
| `canonical` | string | Set the page canonical url. |
| `twitter.cardType` | string | The card type, which will be one of `summary`, `summary_large_image`, `app`, or `player` |
| `twitter.site` | string | @username for the website used in the card footer . |
| `twitter.handle` | string | @username for the content creator / author (outputs as `twitter:creator`) |
| `facebook.appId` | string | Used for Facebook Insights, you must add a facebook app ID to your page to for it |
| `openGraph.type` | string | The type of your object. Depending on the type you specify, other properties may also be required |
| `openGraph.title` | string | The open graph title, this can be different than your meta title. |
| `openGraph.description` | string | The open graph description, this can be different than your meta description. |
| `openGraph.url` | string | The canonical URL of your object that will be used as its permanent ID in the graph. |
| `openGraph.images` | object[] | An array of images to be used as a preview. If multiple supplied you can choose one when sharing. |
| `openGraph.article.publishedTime` | datetime | When the article was first published. . |
| `openGraph.article.modifiedTime` | datetime | When the article was last changed. |
| `openGraph.article.expirationTime` | datetime | When the article is out of date after. |
| `openGraph.article.authors` | string[] | Writers of the article. |
| `openGraph.article.section` | string | A high-level section name. E.g. Technology |
| `openGraph.article.tags` | string[] | Tag words associated with this article. |
| `jsonLd` | object | Data in `ld+json` format. |
| Property | Type | Description |
| ---------------------------------- | ----------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `title` | string | Sets the page meta title. |
| `noindex` | boolean (default false) | Sets whether page should be indexed or not |
| `nofollow` | boolean (default false) | Sets whether page should be followed or not |
| `additionRobotsProps` | Object | Set the more meta information for the X-Robots-Tag |
| `description` | string | Sets the page meta description. |
| `canonical` | string | Set the page canonical url. |
| `mobileAlternate.media` | string | Set what screen size the mobile website should be served from |
| `mobileAlternate.href` | string | Set the mobile page alternate url |
| `languageAlternates` | array | Set the language of the alternate urls. Expects array of objects with the shape: `{ hrefLang: string, href: string }` |
| `twitter.cardType` | string | The card type, which will be one of `summary`, `summary_large_image`, `app`, or `player` |
| `twitter.site` | string | @username for the website used in the card footer . |
| `twitter.handle` | string | @username for the content creator / author (outputs as `twitter:creator`) |
| `facebook.appId` | string | Used for Facebook Insights, you must add a facebook app ID to your page to for it |
| `openGraph.url` | string | The canonical URL of your object that will be used as its permanent ID in the graph. |
| `openGraph.type` | string | The type of your object. Depending on the type you specify, other properties may also be required |
| `openGraph.title` | string | The open graph title, this can be different than your meta title. |
| `openGraph.description` | string | The open graph description, this can be different than your meta description. |
| `openGraph.images` | array | An array of images to be used as a preview. If multiple supplied you can choose one when sharing. |
| `openGraph.videos` | array | An array of videos (object) |
| `openGraph.locale` | string | The locale the open graph tags are marked up in. |
| `openGraph.site_name` | string | If your object is part of a larger web site, the name which should be displayed for the overall site. |
| `openGraph.profile.firstName` | string | Person's first name. |
| `openGraph.profile.lastName` | string | Person's last name. |
| `openGraph.profile.username` | string | Person's username. |
| `openGraph.profile.gender` | string | Person's gender. |
| `openGraph.book.authors` | string[] | Writers of the article. |
| `openGraph.book.isbn` | string | The [ISBN](https://en.wikipedia.org/wiki/International_Standard_Book_Number) |
| `openGraph.book.releaseDate` | datetime | The date the book was released. |
| `openGraph.book.tags` | string[] | Tag words associated with this book. |
| `openGraph.article.publishedTime` | datetime | When the article was first published. |
| `openGraph.article.modifiedTime` | datetime | When the article was last changed. |
| `openGraph.article.expirationTime` | datetime | When the article is out of date after. |
| `openGraph.article.authors` | string[] | Writers of the article. |
| `openGraph.article.section` | string | A high-level section name. E.g. Technology |
| `openGraph.article.tags` | string[] | Tag words associated with this article. |
| `jsonLd` | object | Data in `ld+json` format. |
## License

View File

@ -1,32 +1,68 @@
<script>
export let robots = 'index,follow';
export let title = undefined;
export let noindex = false;
export let nofollow = false;
export let robotsProps = undefined;
export let description = undefined;
export let keywords = undefined;
export let canonical = undefined;
export let mobileAlternate = undefined;
export let languageAlternates = undefined;
export let twitter = undefined;
export let facebook = undefined;
export let openGraph = undefined;
export let canonical = undefined;
export let jsonLd = undefined;
let robotsParams = '';
if (robotsProps) {
const {
nosnippet,
maxSnippet,
maxImagePreview,
maxVideoPreview,
noarchive,
noimageindex,
notranslate,
unavailableAfter
} = robotsProps;
robotsParams = `${nosnippet ? ',nosnippet' : ''}${
maxSnippet ? `,max-snippet:${maxSnippet}` : ''
}${maxImagePreview ? `,max-image-preview:${maxImagePreview}` : ''}${
noarchive ? ',noarchive' : ''
}${unavailableAfter ? `,unavailable_after:${unavailableAfter}` : ''}${
noimageindex ? ',noimageindex' : ''
}${maxVideoPreview ? `,max-video-preview:${maxVideoPreview}` : ''}${
notranslate ? ',notranslate' : ''
}`;
}
</script>
<svelte:head>
<meta name="robots" content={robots} />
{#if title}
<title>{title}</title>
{/if}
<meta
name="robots"
content={`${noindex ? 'noindex' : 'index'},${nofollow ? 'nofollow' : 'follow'}${robotsParams}`}
/>
<meta
name="googlebot"
content={`${noindex ? 'noindex' : 'index'},${nofollow ? 'nofollow' : 'follow'}${robotsParams}`}
/>
{#if description}
<meta name="description" content={description} />
{/if}
{#if canonical}
<link rel="canonical" href={canonical} />
{#if mobileAlternate}
<link rel="alternate" media={mobileAlternate.media} href={mobileAlternate.href} />
{/if}
{#if keywords}
<meta name="keywords" content={keywords} />
{#if languageAlternates && languageAlternates.length > 0}
{#each languageAlternates as languageAlternate}
<link rel="alternate" hrefLang={languageAlternate.hrefLang} href={languageAlternate.href} />
{/each}
{/if}
{#if twitter}
@ -46,50 +82,126 @@
{/if}
{#if openGraph}
{#if openGraph.title}
<meta property="og:title" content={openGraph.title} />
{/if}
{#if openGraph.description}
<meta property="og:description" content={openGraph.description} />
{/if}
{#if openGraph.url || canonical}
<meta property="og:url" content={openGraph.url || canonical} />
{/if}
{#if openGraph.type}
<meta property="og:type" content={openGraph.type.toLowerCase()} />
{#if openGraph.type.toLowerCase() === 'profile' && openGraph.profile}
{#if openGraph.profile.firstName}
<meta property="profile:first_name" content={openGraph.profile.firstName} />
{/if}
{#if openGraph.profile.lastName}
<meta property="profile:last_name" content={openGraph.profile.lastName} />
{/if}
{#if openGraph.profile.username}
<meta property="profile:username" content={openGraph.profile.username} />
{/if}
{#if openGraph.profile.gender}
<meta property="profile:gender" content={openGraph.profile.gender} />
{/if}
{:else if openGraph.type.toLowerCase() === 'book' && openGraph.book}
{#if openGraph.book.authors && openGraph.book.authors.length}
{#each openGraph.book.authors as author}
<meta property="book:author" content={author} />
{/each}
{/if}
{#if openGraph.book.isbn}
<meta property="book:isbn" content={openGraph.book.isbn} />
{/if}
{#if openGraph.book.releaseDate}
<meta property="book:release_date" content={openGraph.book.releaseDate} />
{/if}
{#if openGraph.book.tags && openGraph.book.tags.length}
{#each openGraph.book.tags as tag}
<meta property="book:tags" content={tag} />
{/each}
{/if}
{:else if openGraph.type.toLowerCase() === 'article' && openGraph.article}
{#if openGraph.article.publishedTime}
<meta property="article:published_time" content={openGraph.article.publishedTime} />
{/if}
{#if openGraph.article.modifiedTime}
<meta property="article:modified_time" content={openGraph.article.modifiedTime} />
{/if}
{#if openGraph.article.expirationTime}
<meta property="article:expiration_time" content={openGraph.article.expirationTime} />
{/if}
{#if openGraph.article.authors && openGraph.article.authors.length}
{#each openGraph.article.authors as author}
<meta property="article:author" content={author} />
{/each}
{/if}
{#if openGraph.article.section}
<meta property="article:section" content={openGraph.article.section} />
{/if}
{#if openGraph.article.tags && openGraph.article.tags.length}
{#each openGraph.article.tags as tag}
<meta property="article:tag" content={tag} />
{/each}
{/if}
{:else if openGraph.type.toLowerCase() === 'video.movie' || openGraph.type.toLowerCase() === 'video.episode' || openGraph.type.toLowerCase() === 'video.tv_show' || (openGraph.type.toLowerCase() === 'video.other' && openGraph.video)}
{#if openGraph.video.actors && openGraph.video.actors.length}
{#each openGraph.video.actors as actor}
{#if actor.profile}
<meta property="video:actor" content={actor.profile} />
{/if}
{#if actor.role}
<meta property="video:actor:role" content={actor.role} />
{/if}
{/each}
{/if}
{#if openGraph.video.directors && openGraph.video.directors.length}
{#each openGraph.video.directors as director}
<meta property="video:director" content={director} />
{/each}
{/if}
{#if openGraph.video.writers && openGraph.video.writers.length}
{#each openGraph.video.writers as writer}
<meta property="video:writer" content={writer} />
{/each}
{/if}
{#if openGraph.video.duration}
<meta property="video:duration" content={openGraph.video.duration.toString()} />
{/if}
{#if openGraph.video.releaseDate}
<meta property="video:release_date" content={openGraph.video.releaseDate} />
{/if}
{#if openGraph.video.tags && openGraph.video.tags.length}
{#each openGraph.video.tags as tag}
<meta property="video:tag" content={tag} />
{/each}
{/if}
{#if openGraph.video.series}
<meta property="video:series" content={openGraph.video.series} />
{/if}
{/if}
{/if}
{#if openGraph.article}
{#if openGraph.article.publishedTime}
<meta property="article:published_time" content={openGraph.article.publishedTime} />
{/if}
{#if openGraph.title || title}
<meta property="og:title" content={openGraph.title || title} />
{/if}
{#if openGraph.article.modifiedTime}
<meta property="article:modified_time" content={openGraph.article.modifiedTime} />
{/if}
{#if openGraph.article.expirationTime}
<meta property="article:expiration_time" content={openGraph.article.expirationTime} />
{/if}
{#if openGraph.article.section}
<meta property="article:section" content={openGraph.article.section} />
{/if}
{#if openGraph.article.authors && openGraph.article.authors.length}
{#each openGraph.article.authors as author}
<meta property="article:author" content={author} />
{/each}
{/if}
{#if openGraph.article.tags && openGraph.article.tags.length}
{#each openGraph.article.tags as tag}
<meta property="article:tag" content={tag} />
{/each}
{/if}
{#if openGraph.description || description}
<meta property="og:description" content={openGraph.description || description} />
{/if}
{#if openGraph.images && openGraph.images.length}
@ -106,6 +218,39 @@
{/if}
{/each}
{/if}
{#if openGraph.videos && openGraph.videos.length}
{#each openGraph.videos as video}
<meta property="og:video" content={video.url} />
{#if video.alt}
<meta property="og:video:alt" content={video.alt} />
{/if}
{#if video.width}
<meta property="og:video:width" content={video.width.toString()} />
{/if}
{#if video.height}
<meta property="og:video:height" content={video.height.toString()} />
{/if}
{#if video.secureUrl}
<meta property="og:video:secure_url" content={video.secureUrl.toString()} />
{/if}
{#if video.type}
<meta property="og:video:type" content={video.type.toString()} />
{/if}
{/each}
{/if}
{#if openGraph.locale}
<meta property="og:locale" content={openGraph.locale} />
{/if}
{#if openGraph.site_name}
<meta property="og:site_name" content={openGraph.site_name} />
{/if}
{/if}
{#if canonical}
<link rel="canonical" href={canonical} />
{/if}
{#if jsonLd}

View File

@ -1,21 +1,27 @@
import { SvelteComponentTyped } from 'svelte';
import { Thing, WithContext } from 'schema-dts';
import { OpenGraph, Twitter, Facebook } from './types';
import {
AdditionalRobotsProps,
MobileAlternate,
LanguageAlternate,
Twitter,
Facebook,
OpenGraph
} from './types';
export interface MetaTagsProps {
robots?: string;
title?: string;
noindex?: boolean;
nofollow?: boolean;
robotsProps?: AdditionalRobotsProps;
description?: string;
keywords?: string;
canonical?: string;
mobileAlternate?: MobileAlternate;
languageAlternates?: ReadonlyArray<LanguageAlternate>;
twitter?: Twitter;
facebook?: Facebook;
openGraph?: OpenGraph;
jsonLd?: Thing | WithContext<Thing>;
}
export default class MetaTags extends SvelteComponentTyped<
MetaTagsProps,
Record<string, never>,
Record<string, never>
> {}
export default class MetaTags extends SvelteComponentTyped<MetaTagsProps> {}

78
src/lib/types.d.ts vendored
View File

@ -1,26 +1,61 @@
export interface OpenGraph {
title?: string;
description?: string;
url?: string;
type?: string;
title?: string;
description?: string;
images?: ReadonlyArray<OpenGraphImages>;
videos?: ReadonlyArray<OpenGraphVideos>;
locale?: string;
site_name?: string;
profile?: OpenGraphProfile;
book?: OpenGraphBook;
article?: OpenGraphArticle;
images?: OpenGraphImage[];
video?: OpenGraphVideo;
}
export interface OpenGraphImages {
url: string;
alt?: string;
width?: number;
height?: number;
}
export interface OpenGraphVideos {
url: string;
alt?: string;
width?: number;
height?: number;
secureUrl?: string;
type?: string;
}
export interface OpenGraphProfile {
firstName?: string;
lastName?: string;
username?: string;
gender?: string;
}
export interface OpenGraphBook {
authors?: ReadonlyArray<string>;
isbn?: string;
releaseDate?: string;
tags?: ReadonlyArray<string>;
}
export interface OpenGraphArticle {
publishedTime?: string;
modifiedTime?: string;
expirationTime?: string;
authors?: ReadonlyArray<string>;
section?: string;
authors?: string[];
tags?: string[];
tags?: ReadonlyArray<string>;
}
export interface OpenGraphImage {
url: string;
alt?: string;
width?: number | string;
height?: number | string;
export interface OpenGraphVideo {
actors?: ReadonlyArray<OpenGraphVideoActors>;
directors?: ReadonlyArray<string>;
writers?: ReadonlyArray<string>;
duration?: number;
releaseDate?: string;
tags?: ReadonlyArray<string>;
series?: string;
}
export interface Twitter {
@ -32,3 +67,26 @@ export interface Twitter {
export interface Facebook {
appId?: string;
}
export interface MobileAlternate {
media: string;
href: string;
}
export interface LanguageAlternate {
hrefLang: string;
href: string;
}
export interface AdditionalRobotsProps {
nosnippet?: boolean;
maxSnippet?: number;
maxImagePreview?: ImagePrevSize;
maxVideoPreview?: number;
noarchive?: boolean;
unavailableAfter?: string;
noimageindex?: boolean;
notranslate?: boolean;
}
export type ImagePrevSize = 'none' | 'standard' | 'large';