Skip to content

Svelte Meta Tags provides components designed to help you manage SEO for Svelte projects.

License

Notifications You must be signed in to change notification settings

shamokit/svelte-meta-tags

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

svelte-meta-tags

CI download npm MIT

Svelte Meta Tags provides components designed to help you manage SEO for Svelte projects.

Demo

This library is inspired by next-seo

Table of Contents

📦 Installing

npm install -D svelte-meta-tags

or

yarn add -D svelte-meta-tags

or

pnpm add -D svelte-meta-tags

🚀 Usage

Example with just title and description:

<script>
  import { MetaTags } from 'svelte-meta-tags';
</script>

<MetaTags title="Example Title" description="Example Description." />

Typical page example:

<script>
  import { MetaTags } from 'svelte-meta-tags';
</script>

<MetaTags
  title="Using More of Config"
  titleTemplate="%s | Svelte Meta Tags"
  description="This example uses more of the available config options."
  canonical="https://www.canonical.ie/"
  openGraph={{
    url: 'https://www.url.ie/a',
    title: 'Open Graph Title',
    description: 'Open Graph Description',
    images: [
      {
        url: 'https://www.example.ie/og-image-01.jpg',
        width: 800,
        height: 600,
        alt: 'Og Image Alt'
      },
      {
        url: 'https://www.example.ie/og-image-02.jpg',
        width: 900,
        height: 800,
        alt: 'Og Image Alt Second'
      },
      { url: 'https://www.example.ie/og-image-03.jpg' },
      { url: 'https://www.example.ie/og-image-04.jpg' }
    ],
    site_name: 'SiteName'
  }}
  twitter={{
    handle: '@handle',
    site: '@site',
    cardType: 'summary_large_image',
    title: 'Using More of Config',
    description: 'This example uses more of the available config options.',
    image: 'https://www.example.ie/twitter-image.jpg',
    imageAlt: 'Twitter image alt'
  }}
  facebook={{
    appId: '1234567890'
  }}
/>

MetaTags Properties

Property Type Description
title string Sets the meta title of the page
titleTemplate string Allows you to set the default title template that will be added to your title More Info
noindex boolean (default false) Specifies whether the page should be indexed or not
nofollow boolean (default false) Specifies whether or not to follow the page
additionRobotsProps Object Set the additional meta information for the X-Robots-Tag More Info
description string Sets the meta description of the page
canonical string Make the page canonical URL
mobileAlternate.media string Set the screen size from which the mobile site will be served
mobileAlternate.href string Set the alternate URL for the mobile page
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
additionalLinkTags array Allows you to add a link tag that is not documented here More Info
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 creator of the content (output as twitter:creator)
twitter.title string The concise title for the related content
twitter.description string The description that concisely summarizes the content in a manner suitable for presentation within a Tweet. You should not reuse 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 that represents the content of the page. You should not use a generic image such as your site logo, author photo, or other image that spans multiple pages. Images for this card support a 1:1 aspect ratio with a minimum size of 144x144 pixels or a maximum size 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 is used. SVG is not supported
twitter.imageAlt string The textual description of the image that conveys the essence of the image to visually impaired users. Maximum 420 characters
facebook.appId string For Facebook Insights, you will need to add a Facebook app ID to your page in order to use it
openGraph.url string The canonical URL of your object, which 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
openGraph.title string The open graph title, this can be different from your meta title
openGraph.description string The open graph description, which may be different from your meta description
openGraph.images array An array of images to use as previews. If multiple are provided, you can choose one when sharing See Examples
openGraph.videos array An array of videos (object)
openGraph.locale string The locale in which the open graph tags are highlighted
openGraph.site_name string If your item is part of a larger website, the name that should be displayed for the entire 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[] Author of the article See Examples
openGraph.book.isbn string The ISBN
openGraph.book.releaseDate datetime The date the book was released
openGraph.book.tags string[] Tag words related to this book
openGraph.article.publishedTime datetime When the article was first published See Examples
openGraph.article.modifiedTime datetime When the item was last modified
openGraph.article.expirationTime datetime When the article is out of date after
openGraph.article.authors string[] Author 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

Replace %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

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'
}}

See out the Twitter documentation for more information.

Facebook

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 on this can be found in Facebook's documentation.

robotsProps

In addition to index, follow', the robots' meta tag accepts more properties to archive more accurate crawling and serve better snippets to SEO bots crawling your page.

Example:

<script>
  import { MetaTags } from 'svelte-meta-tags';
</script>

<MetaTags
  robotsProps={{
    noarchive: true,
    nosnippet: true,
    maxSnippet: -1,
    maxImagePreview: 'none',
    maxVideoPreview: -1,
    notranslate: true,
    noimageindex: true,
    unavailableAfter: '25 Jun 2010 15:00:00 PST'
  }}
/>

Available properties

Property Type Description
noarchive boolean Do not display a cached link 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 the text snippet for this search result Read more
maxImagePreview 'none','standard','large' Set the maximum size of an image preview for this page in a search result
maxVideoPreview number Use a maximum of [number] seconds as a video snippet for videos on this page in search results Read more
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 in a widely accepted format, including but not limited to RFC 822, RFC 850, and ISO 8601

For more information on the X-Robots-Tag visit Google Search Central - Control Crawling and Indexing

Alternate

This link relationship is used to indicate a relationship between a desktop and mobile website to search engines.

Example:

mobileAlternate={{
  media: 'only screen and (max-width: 640px)',
  href: 'https://m.canonical.ie'
}}
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 required by the config.

content is required. Then either name, property or httpEquiv. (only one of each)

Example:

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 because they contain more than one of name, property, and httpEquiv in the same entry.

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:

additionalMetaTags={[
  {
    property: 'dc:creator',
    content: 'John Doe'
  },
  {
    property: 'dc:creator',
    content: 'Jane Doe'
  }
]}

it will result in this being rendered:

<meta property="dc:creator" content="Jane Doe" />,

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:

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: 'https://www.test.ie/manifest.json'
  }
]}

it will result in this being rendered:

<link rel="icon" href="https://www.test.ie/favicon.ico" />
<link rel="apple-touch-icon" href="https://www.test.ie/touch-icon-ipad.jpg" sizes="76x76" />
<link rel="manifest" href="https://www.test.ie/manifest.json" />

Open Graph

The full specification can be found at http://ogp.me/.

Svelte Meta Tags currently supports:

Open Graph Examples

Basic

<script>
  import { MetaTags } from 'svelte-meta-tags';
</script>

<MetaTags
  openGraph={{
    type: 'website',
    url: 'https://www.example.com/page',
    title: 'Open Graph Title',
    description: 'Open Graph Description',
    images: [
      {
        url: 'https://www.example.ie/og-image.jpg',
        width: 800,
        height: 600,
        alt: 'Og Image Alt'
      },
      {
        url: 'https://www.example.ie/og-image-2.jpg',
        width: 800,
        height: 600,
        alt: 'Og Image Alt 2'
      }
    ]
  }}
/>

Video

Full info on http://ogp.me/

<script>
  import { MetaTags } from 'svelte-meta-tags';
</script>

<MetaTags
  title="Video Page Title"
  description="Description of video page"
  openGraph={{
    title: 'Open Graph Video Title',
    description: 'Description of open graph video',
    url: 'https://www.example.com/videos/video-title',
    type: 'video.movie',
    video: {
      actors: [
        {
          profile: 'https://www.example.com/actors/@firstnameA-lastnameA',
          role: 'Protagonist'
        },
        {
          profile: 'https://www.example.com/actors/@firstnameB-lastnameB',
          role: 'Antagonist'
        }
      ],
      directors: [
        'https://www.example.com/directors/@firstnameA-lastnameA',
        'https://www.example.com/directors/@firstnameB-lastnameB'
      ],
      writers: [
        'https://www.example.com/writers/@firstnameA-lastnameA',
        'https://www.example.com/writers/@firstnameB-lastnameB'
      ],
      duration: 680000,
      releaseDate: '2022-12-21T22:04:11Z',
      tags: ['Tag A', 'Tag B', 'Tag C']
    },
    site_name: 'SiteName'
  }}
/>

Article

<script>
  import { MetaTags } from 'svelte-meta-tags';
</script>

<MetaTags
  openGraph={{
    title: 'Open Graph Article Title',
    description: 'Description of open graph article',
    url: 'https://www.example.com/articles/article-title',
    type: 'article',
    article: {
      publishedTime: '2017-06-21T23:04:13Z',
      modifiedTime: '2018-01-21T18:04:43Z',
      expirationTime: '2022-12-21T22:04:11Z',
      section: 'Section II',
      authors: [
        'https://www.example.com/authors/@firstnameA-lastnameA',
        'https://www.example.com/authors/@firstnameB-lastnameB'
      ],
      tags: ['Tag A', 'Tag B', 'Tag C']
    },
    images: [
      {
        url: 'https://www.test.ie/images/cover.jpg',
        width: 850,
        height: 650,
        alt: 'Photo of text'
      }
    ]
  }}
/>

Book

<script>
  import { MetaTags } from 'svelte-meta-tags';
</script>

<MetaTags
  openGraph={{
    title: 'Open Graph Book Title',
    description: 'Description of open graph book',
    url: 'https://www.example.com/books/book-title',
    type: 'book',
    book: {
      releaseDate: '2018-09-17T11:08:13Z',
      isbn: '978-3-16-148410-0',
      authors: [
        'https://www.example.com/authors/@firstnameA-lastnameA',
        'https://www.example.com/authors/@firstnameB-lastnameB'
      ],
      tags: ['Tag A', 'Tag B', 'Tag C']
    },
    images: [
      {
        url: 'https://www.test.ie/images/book.jpg',
        width: 850,
        height: 650,
        alt: 'Cover of the book'
      }
    ]
  }}
/>

Profile

<script>
  import { MetaTags } from 'svelte-meta-tags';
</script>

<MetaTags
  openGraph={{
    title: 'Open Graph Profile Title',
    description: 'Description of open graph profile',
    url: 'https://www.example.com/@firstlast123',
    type: 'profile',
    profile: {
      firstName: 'First',
      lastName: 'Last',
      username: 'firstlast123',
      gender: 'female'
    },
    images: [
      {
        url: 'https://www.test.ie/images/profile.jpg',
        width: 850,
        height: 650,
        alt: 'Profile Photo'
      }
    ]
  }}
/>

JSON-LD

JSON-LD allows for more customized and richer display, such as in search results.

To discover all the different content types that JSON-LD offers, go to: https://developers.google.com/search/docs/guides/search-gallery

Tips: If you want to handle multiple JSON-LDs on one page, pass an array to the schema.

Using schema-dts

This plugin uses schema-dts, so it provides other types than the examples below.

JSON-LD Properties

Property Type Description
output string (default head) Specifies whether to output json-ld in <head> or <body>. Possible values are either head or body
schema Object Data in ld+json format See Examples

JSON-LD Examples

Article

<script>
  import { JsonLd } from 'svelte-meta-tags';
</script>

<JsonLd
  schema={{
    '@type': 'Article',
    mainEntityOfPage: {
      '@type': 'WebPage',
      '@id': 'https://example.com/article'
    },
    headline: 'Article headline',
    image: [
      'https://example.com/photos/1x1/photo.jpg',
      'https://example.com/photos/4x3/photo.jpg',
      'https://example.com/photos/16x9/photo.jpg'
    ],
    datePublished: '2015-02-05T08:00:00+08:00',
    dateModified: '2015-02-05T09:20:00+08:00',
    author: {
      '@type': 'Person',
      name: 'John Doe'
    },
    publisher: {
      '@type': 'Organization',
      name: 'Google',
      logo: {
        '@type': 'ImageObject',
        url: 'https://example.com/logo.jpg'
      }
    }
  }}
/>

Breadcrumb

<script>
  import { JsonLd } from 'svelte-meta-tags';
</script>

<JsonLd
  schema={{
    '@type': 'BreadcrumbList',
    itemListElement: [
      {
        '@type': 'ListItem',
        position: 1,
        name: 'Books',
        item: 'https://example.com/books'
      },
      {
        '@type': 'ListItem',
        position: 2,
        name: 'Science Fiction',
        item: 'https://example.com/books/sciencefiction'
      },
      {
        '@type': 'ListItem',
        position: 3,
        name: 'Award Winners'
      }
    ]
  }}
/>

Product

<script>
  import { JsonLd } from 'svelte-meta-tags';
</script>

<JsonLd
  schema={{
    '@type': 'Product',
    name: 'Executive Anvil',
    image: [
      'https://example.com/photos/1x1/photo.jpg',
      'https://example.com/photos/4x3/photo.jpg',
      'https://example.com/photos/16x9/photo.jpg'
    ],
    description:
      "Sleeker than ACME's Classic Anvil, the Executive Anvil is perfect for the business traveler looking for something to drop from a height.",
    sku: '0446310786',
    mpn: '925872',
    brand: {
      '@type': 'Brand',
      name: 'ACME'
    },
    review: {
      '@type': 'Review',
      reviewRating: {
        '@type': 'Rating',
        ratingValue: '4',
        bestRating: '5'
      },
      author: {
        '@type': 'Person',
        name: 'Fred Benson'
      }
    },
    aggregateRating: {
      '@type': 'AggregateRating',
      ratingValue: '4.4',
      reviewCount: '89'
    },
    offers: {
      '@type': 'Offer',
      url: 'https://example.com/anvil',
      priceCurrency: 'USD',
      price: '119.99',
      priceValidUntil: '2020-11-20',
      itemCondition: 'https://schema.org/UsedCondition',
      availability: 'https://schema.org/InStock'
    }
  }}
/>

Course

<script>
  import { JsonLd } from 'svelte-meta-tags';
</script>

<JsonLd
  schema={{
    '@type': 'Course',
    name: 'Introduction to Computer Science and Programming',
    description: 'Introductory CS course laying out the basics.',
    provider: {
      '@type': 'Organization',
      name: 'University of Technology - Eureka',
      sameAs: 'http://www.ut-eureka.edu'
    }
  }}
/>

DataSet

<script>
  import { JsonLd } from 'svelte-meta-tags';
</script>

<JsonLd
  schema={{
    '@type': 'Dataset',
    name: 'name of the dataset',
    description: 'The description needs to be at least 50 characters long',
    license: 'https//www.example.com'
  }}
/>

FAQ

<script>
  import { JsonLd } from 'svelte-meta-tags';
</script>

<JsonLd
  schema={{
    '@type': 'FAQPage',
    mainEntity: [
      {
        '@type': 'Question',
        name: 'How long is the delivery time?',
        acceptedAnswer: {
          '@type': 'Answer',
          text: '3-5 business days.'
        }
      },
      {
        '@type': 'Question',
        name: 'Where can I find information about product recalls?',
        acceptedAnswer: {
          '@type': 'Answer',
          text: 'Read more on under information.'
        }
      }
    ]
  }}
/>

JSON-LD Multiple Examples

<script>
  import { JsonLd } from 'svelte-meta-tags';
</script>

<JsonLd
  schema={[
    {
      '@type': 'BreadcrumbList',
      itemListElement: [
        {
          '@type': 'ListItem',
          position: 1,
          name: 'Books',
          item: 'https://example.com/books'
        },
        {
          '@type': 'ListItem',
          position: 2,
          name: 'Science Fiction',
          item: 'https://example.com/books/sciencefiction'
        },
        {
          '@type': 'ListItem',
          position: 3,
          name: 'Award Winners'
        }
      ]
    },
    {
      '@type': 'NewsArticle',
      mainEntityOfPage: {
        '@type': 'WebPage',
        '@id': 'https://google.com/article'
      },
      headline: 'Article headline',
      image: [
        'https://example.com/photos/1x1/photo.jpg',
        'https://example.com/photos/4x3/photo.jpg',
        'https://example.com/photos/16x9/photo.jpg'
      ],
      datePublished: '2015-02-05T08:00:00+08:00',
      dateModified: '2015-02-05T09:20:00+08:00',
      author: {
        '@type': 'Person',
        name: 'John Doe'
      },
      publisher: {
        '@type': 'Organization',
        name: 'Google',
        logo: {
          '@type': 'ImageObject',
          url: 'https://google.com/logo.jpg'
        }
      }
    }
  ]}
/>

Types

The following types can be imported from svelte-meta-tags

MetaTagsProps

interface MetaTagsProps {
  title?: string;
  titleTemplate?: string;
  noindex?: boolean;
  nofollow?: boolean;
  robotsProps?: AdditionalRobotsProps;
  description?: string;
  canonical?: string;
  mobileAlternate?: MobileAlternate;
  languageAlternates?: ReadonlyArray<LanguageAlternate>;
  twitter?: Twitter;
  facebook?: Facebook;
  openGraph?: OpenGraph;
  additionalMetaTags?: ReadonlyArray<MetaTag>;
  additionalLinkTags?: ReadonlyArray<LinkTag>;
}

JsonLdProps

interface JsonLdProps {
  output?: 'head' | 'body';
  schema?: Thing | WithContext<Thing> | Thing[] | WithContext<Thing>[];
}

AdditionalRobotsProps

interface AdditionalRobotsProps {
  nosnippet?: boolean;
  maxSnippet?: number;
  maxImagePreview?: 'none' | 'standard' | 'large';
  maxVideoPreview?: number;
  noarchive?: boolean;
  unavailableAfter?: string;
  noimageindex?: boolean;
  notranslate?: boolean;
}

MobileAlternate

interface MobileAlternate {
  media: string;
  href: string;
}

LanguageAlternate

interface LanguageAlternate {
  hrefLang: string;
  href: string;
}

Twitter

interface Twitter {
  cardType?: 'summary' | 'summary_large_image' | 'app' | 'player';
  site?: string;
  handle?: string;
  title?: string;
  description?: string;
  image?: string;
  imageAlt?: string;
}

Facebook

interface Facebook {
  appId?: string;
}

OpenGraph

interface OpenGraph {
  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;
  video?: OpenGraphVideo;
}

MetaTag

type MetaTag = HTML5MetaTag | RDFaMetaTag | HTTPEquivMetaTag;

LinkTag

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

interface OpenGraphImages {
  url: string;
  alt?: string;
  width?: number;
  height?: number;
}

OpenGraphVideos

interface OpenGraphVideos {
  url: string;
  alt?: string;
  width?: number;
  height?: number;
  secureUrl?: string;
  type?: string;
}

OpenGraphProfile

interface OpenGraphProfile {
  firstName?: string;
  lastName?: string;
  username?: string;
  gender?: string;
}

OpenGraphBook

interface OpenGraphBook {
  authors?: ReadonlyArray<string>;
  isbn?: string;
  releaseDate?: string;
  tags?: ReadonlyArray<string>;
}

OpenGraphArticle

interface OpenGraphArticle {
  publishedTime?: string;
  modifiedTime?: string;
  expirationTime?: string;
  authors?: ReadonlyArray<string>;
  section?: string;
  tags?: ReadonlyArray<string>;
}

OpenGraphVideo

interface OpenGraphVideo {
  actors?: ReadonlyArray<OpenGraphVideoActors>;
  directors?: ReadonlyArray<string>;
  writers?: ReadonlyArray<string>;
  duration?: number;
  releaseDate?: string;
  tags?: ReadonlyArray<string>;
  series?: string;
}

OpenGraphVideoActors

interface OpenGraphVideoActors {
  profile: string;
  role?: string;
}

BaseMetaTag

interface BaseMetaTag {
  content: string;
}

HTML5MetaTag

interface HTML5MetaTag extends BaseMetaTag {
  name: string;
  property?: undefined;
  httpEquiv?: undefined;
}

RDFaMetaTag

interface RDFaMetaTag extends BaseMetaTag {
  property: string;
  name?: undefined;
  httpEquiv?: undefined;
}

HTTPEquivMetaTag

interface HTTPEquivMetaTag extends BaseMetaTag {
  httpEquiv: 'content-security-policy' | 'content-type' | 'default-style' | 'x-ua-compatible' | 'refresh';
  name?: undefined;
  property?: undefined;
}

License

MIT

About

Svelte Meta Tags provides components designed to help you manage SEO for Svelte projects.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 54.1%
  • Svelte 43.7%
  • JavaScript 1.6%
  • Other 0.6%