svelte-meta-tags [![CI](https://github.com/oekazuma/svelte-meta-tags/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/oekazuma/svelte-meta-tags/actions/workflows/ci.yml) [![download](https://img.shields.io/npm/dt/svelte-meta-tags.svg)](https://www.npmjs.com/package/svelte-meta-tags) [![npm](https://img.shields.io/npm/v/svelte-meta-tags)](https://www.npmjs.com/package/svelte-meta-tags) [![MIT](https://img.shields.io/npm/l/svelte-meta-tags)](https://opensource.org/licenses/MIT) Svelte Meta Tags is a plugin that makes managing your SEO easier in Svelte projects. [Demo](https://svelte.dev/repl/ffd783c9b8e54d97b6b7cac6eadace42) This library is inspired by [next-seo](https://github.com/garmeeh/next-seo) **Table of Contents** - [Installing](#-installing) - [Usage](#-usage) - [MetaTags Properties](#metatags-properties) - [Title Template](#title-template) - [Twitter](#twitter) - [Facebook](#facebook) - [robotsProps](#robotsprops) - [Alternate](#alternate) - [Additional Meta Tags](#additional-meta-tags) - [Additional Link Tags](#additional-link-tags) - [Open Graph](#open-graph) - [Open Graph Examples](#open-graph-examples) - [Basic](#basic) - [Video](#video) - [Article](#article) - [Book](#book) - [Profile](#profile) - [JSON-LD](#json-ld) - [Using schema-dts](#using-schema-dts) - [JSON-LD Properties](#json-ld-properties) - [JSON-LD Examples](#json-ld-examples) - [Article](#article) - [Breadcrumb](#breadcrumb) - [Product](#product) - [Course](#course) - [DataSet](#dataset) - [FAQ](#faq) - [Types](#types) - [Additional types](#additional-types) ### 📦 Installing ```shell npm install -D svelte-meta-tags ``` or ```shell yarn add -D svelte-meta-tags ``` or ```shell pnpm add -D svelte-meta-tags ``` ### 🚀 Usage **Example with just title and description:** ```svelte ``` **Typical page example:** ```svelte ``` ### MetaTags Properties | Property | Type | Description | | ---------------------------------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `title` | string | Sets the page meta title. | | `titleTemplate` | string | Allows you to set default title template that will be added to your title [More Info](#title-template) | | `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` [More Info](#robotsprops) | | `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 }` | | `additionalMetaTags` | array | Allows you to add a meta tag that is not documented here. [More Info](#additional-meta-tags) | | `additionalLinkTags` | array | Allows you to add a link tag that is not documented here. [More Info](#additional-link-tags) | | `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`) | | `twitter.title` | string | The concise title for the related content | | `twitter.description` | string | The description that concisely summarizes the content as appropriate for presentation within a Tweet. You should not re-use the title as the description or use this field to describe the general services provided by the website | | `twitter.image` | string | The URL to a unique image representing the content of the page. You should not use a generic image such as your website logo, author photo, or other image that spans multiple pages. Images for this Card support an aspect ratio of 1:1 with minimum dimensions of 144x144 or maximum of 4096x4096 pixels. Images must be less than 5MB in size. The image will be cropped to a square on all platforms. JPG, PNG, WEBP and GIF formats are supported. Only the first frame of an animated GIF will be used. SVG is not supported | | `twitter.imageAlt` | string | The text description of the image conveying the essential nature of an image to users who are visually impaired. Maximum 420 characters. | | `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 [More Info](#open-graph) | | `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. [See Examples](#open-graph-examples) | | `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. [See Examples](#open-graph-examples) | | `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. [See Examples](#open-graph-examples) | | `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. | #### Title Template Replaces `%s` with your title string ``` title = 'This is my title' titleTemplate = 'Svelte Meta Tags | %s' // outputs: Svelte Meta Tags | This is my title ``` ``` title = 'This is my title' titleTemplate = '%s | Svelte Meta Tags' // outputs: This is my title | Svelte Meta Tags ``` #### Twitter ```js twitter={{ handle: '@handle', site: '@site', cardType: 'summary_large_image', title: 'Twitter', description: 'Twitter', image: 'https://www.example.ie/twitter-image.jpg', imageAlt: 'Twitter image alt' }} ``` Check out the Twitter [documentation](https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/summary) for more information. #### Facebook ```js facebook={{ appId: '1234567890', }} ``` Add this to your SEO config to include the fb:app_id meta if you need to enable Facebook insights for your site. Information regarding this can be found in facebook's [documentation](https://developers.facebook.com/docs/sharing/webmasters/) #### robotsProps In addition to `index, follow` the `robots` meta tag accepts more properties to archive a more accurate crawling and serve better snippets for SEO bots that crawl your page. Example: ```svelte ``` **Available properties** | Property | Type | Description | | ------------------ | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `noarchive` | boolean | Do not show a [cached link](https://support.google.com/websearch/answer/1687222) in search results. | | `nosnippet` | boolean | Do not show a text snippet or video preview in the search results for this page. | | `maxSnippet` | number | Use a maximum of [number] characters as a textual snippet for this search result. [Read more](https://developers.google.com/search/reference/robots_meta_tag?hl=en-GB#directives) | | `maxImagePreview` | 'none','standard','large' | Set the maximum size of an image preview for this page in a search results. | | `maxVideoPreview` | number | Use a maximum of [number] seconds as a video snippet for videos on this page in search results. [Read more](https://developers.google.com/search/reference/robots_meta_tag?hl=en-GB#directives) | | `notranslate` | boolean | Do not offer translation of this page in search results. | | `noimageindex` | boolean | Do not index images on this page. | | `unavailableAfter` | string | Do not show this page in search results after the specified date/time. The date/time must be specified in a widely adopted format including, but not limited to RFC 822, RFC 850, and ISO 8601. | For more reference about the `X-Robots-Tag` visit [Google Search Central - Control Crawling and Indexing](https://developers.google.com/search/reference/robots_meta_tag?hl=en-GB#directives) #### Alternate This link relation is used to indicate a relation between a desktop and a mobile website to search engines. Example: ```js mobileAlternate={{ media: 'only screen and (max-width: 640px)', href: 'https://m.canonical.ie' }} ``` ```js languageAlternates={[ { hrefLang: 'de-AT', href: 'https://www.canonical.ie/de' } ]} ``` #### Additional Meta Tags This allows you to add any other meta tags that are not covered in the `config`. `content` is required. Then either `name`, `property` or `httpEquiv`. (Only one on each) Example: ```js additionalMetaTags={[ { property: 'dc:creator', content: 'Jane Doe' }, { name: 'application-name', content: 'Svelte-Meta-Tags' }, { httpEquiv: 'x-ua-compatible', content: 'IE=edge; chrome=1' } ]} ``` Invalid Examples: These are invalid as they contain more than one of `name`, `property` and `httpEquiv` on the same entry. ```js additionalMetaTags={[ { property: 'dc:creator', name: 'dc:creator', content: 'Jane Doe' }, { property: 'application-name', httpEquiv: 'application-name', content: 'Svelte-Meta-Tags' } ]} ``` One thing to note on this is that it currently only supports unique tags. This means it will only render one tag per unique `name` / `property` / `httpEquiv`. The last one defined will be rendered. Example: If you pass: ```js additionalMetaTags={[ { property: 'dc:creator', content: 'John Doe' }, { property: 'dc:creator', content: 'Jane Doe' } ]} ``` it will result in this being rendered: ```html , ``` #### Additional Link Tags This allows you to add any other link tags that are not covered in the `config`. `rel` and `href` is required. Example: ```js additionalLinkTags={[ { rel: 'icon', href: 'https://www.test.ie/favicon.ico' }, { rel: 'apple-touch-icon', href: 'https://www.test.ie/touch-icon-ipad.jpg', sizes: '76x76' }, { rel: 'manifest', href: '/manifest.json' } ]} ``` it will result in this being rendered: ```html ``` ## Open Graph For the full specification please check out Svelte Meta Tags currently supports: - [Basic](#basic) - [Video](#video) - [Article](#article) - [Book](#book) - [Profile](#profile) ### Open Graph Examples #### Basic ```svelte ``` #### Video Full info on [http://ogp.me/](http://ogp.me/#type_video) ```svelte ``` #### Article ```svelte ``` #### Book ```svelte ``` #### Profile ```svelte ``` ## JSON-LD JSON-LD allow for more customized and rich representation for example in search results. To discover all the different content types JSON-LD offers check out: https://developers.google.com/search/docs/guides/search-gallery It is also possible to use multiple `` components in a single page. ### Using `schema-dts` This plugin uses [schema-dts](https://github.com/google/schema-dts), so it also provides types other than the usage examples below. ### JSON-LD Properties | Property | Type | Description | | -------- | --------------------- | ---------------------------------------------------------------------------------------------------- | | `output` | string (default head) | Sets whether json-ld is output to `` or ``. Possible values are either `head` or `body`. | | `schema` | Object | Data in `ld+json` format. [See Examples](#json-ld-examples) | ### JSON-LD Examples #### Article ```svelte ``` #### Breadcrumb ```svelte ``` #### Product ```svelte ``` #### Course ```svelte ``` #### DataSet ```svelte ``` #### FAQ ```svelte ``` ## Types The following types can be imported from `svelte-meta-tags` ### MetaTagsProps ```ts interface MetaTagsProps { title?: string; titleTemplate?: string; noindex?: boolean; nofollow?: boolean; robotsProps?: AdditionalRobotsProps; description?: string; canonical?: string; mobileAlternate?: MobileAlternate; languageAlternates?: ReadonlyArray; twitter?: Twitter; facebook?: Facebook; openGraph?: OpenGraph; additionalMetaTags?: ReadonlyArray; additionalLinkTags?: ReadonlyArray; } ``` ### JsonLdProps ```ts interface JsonLdProps { output?: 'head' | 'body'; schema?: Thing | WithContext; } ``` ### AdditionalRobotsProps ```ts interface AdditionalRobotsProps { nosnippet?: boolean; maxSnippet?: number; maxImagePreview?: 'none' | 'standard' | 'large'; maxVideoPreview?: number; noarchive?: boolean; unavailableAfter?: string; noimageindex?: boolean; notranslate?: boolean; } ``` ### MobileAlternate ```ts interface MobileAlternate { media: string; href: string; } ``` ### LanguageAlternate ```ts interface LanguageAlternate { hrefLang: string; href: string; } ``` ### Twitter ```ts interface Twitter { cardType?: 'summary' | 'summary_large_image' | 'app' | 'player'; site?: string; handle?: string; title?: string; description?: string; image?: string; imageAlt?: string; } ``` ### Facebook ```ts interface Facebook { appId?: string; } ``` ### OpenGraph ```ts interface OpenGraph { url?: string; type?: string; title?: string; description?: string; images?: ReadonlyArray; videos?: ReadonlyArray; locale?: string; site_name?: string; profile?: OpenGraphProfile; book?: OpenGraphBook; article?: OpenGraphArticle; video?: OpenGraphVideo; } ``` ### MetaTag ```ts type MetaTag = HTML5MetaTag | RDFaMetaTag | HTTPEquivMetaTag; ``` ### LinkTag ```ts interface LinkTag { rel: string; href: string; sizes?: string; type?: string; color?: string; } ``` ## Additional types The following are referenced by the public types documented above, but cannot be imported directly ### OpenGraphImages ```ts interface OpenGraphImages { url: string; alt?: string; width?: number; height?: number; } ``` ### OpenGraphVideos ```ts interface OpenGraphVideos { url: string; alt?: string; width?: number; height?: number; secureUrl?: string; type?: string; } ``` ### OpenGraphProfile ```ts interface OpenGraphProfile { firstName?: string; lastName?: string; username?: string; gender?: string; } ``` ### OpenGraphBook ```ts interface OpenGraphBook { authors?: ReadonlyArray; isbn?: string; releaseDate?: string; tags?: ReadonlyArray; } ``` ### OpenGraphArticle ```ts interface OpenGraphArticle { publishedTime?: string; modifiedTime?: string; expirationTime?: string; authors?: ReadonlyArray; section?: string; tags?: ReadonlyArray; } ``` ### OpenGraphVideo ```ts interface OpenGraphVideo { actors?: ReadonlyArray; directors?: ReadonlyArray; writers?: ReadonlyArray; duration?: number; releaseDate?: string; tags?: ReadonlyArray; series?: string; } ``` ### OpenGraphVideoActors ```ts interface OpenGraphVideoActors { profile: string; role?: string; } ``` ### BaseMetaTag ```ts interface BaseMetaTag { content: string; } ``` ### HTML5MetaTag ```ts interface HTML5MetaTag extends BaseMetaTag { name: string; property?: undefined; httpEquiv?: undefined; } ``` ### RDFaMetaTag ```ts interface RDFaMetaTag extends BaseMetaTag { property: string; name?: undefined; httpEquiv?: undefined; } ``` ### HTTPEquivMetaTag ```ts interface HTTPEquivMetaTag extends BaseMetaTag { httpEquiv: 'content-security-policy' | 'content-type' | 'default-style' | 'x-ua-compatible' | 'refresh'; name?: undefined; property?: undefined; } ``` ## License MIT