Manage SEO Metadata in Svelte Applications – Svelte SEO

Configure SEO metadata in Svelte apps with Open Graph, Twitter Cards, and schema.org structured data through a single component.

Svelte SEO is a component library that manages meta tags, Open Graph properties, Twitter Cards, and JSON-LD structured data in Svelte applications.

It handles the configuration of HTML head elements to optimize pages for search engines and social media platforms.

You can use the library to configure everything from basic title and description tags to complex Open Graph images and JSON-LD schemas.

The package supports multiple social platforms and structured data formats. It handles the technical details of meta tag implementation so you can focus on content strategy and page structure.

Features

🔧 Meta Tag Management: Handles title, description, keywords, canonical URLs, and other standard HTML meta elements for search engine indexing.

🌐 Open Graph Support: Configures Facebook and social media sharing previews with properties for titles, descriptions, images, videos, and content types like articles, profiles, and media.

🐦 X(Twitter) Card Integration: Generates Twitter-specific meta tags for summary cards, large image cards, player cards, and app cards with proper sizing and attribution.

📱 Progressive Web App Metadata: Manages PWA-related tags like manifest links, theme colors, and application names for installable web apps.

🔍 JSON-LD Structured Data: Implements schema.org markup for rich search results with support for websites, articles, organizations, products, and other entity types.

🌍 Multi-Language Configuration: Handles alternate language tags and locale specifications for international sites with multiple language versions.

🎯 Per-Page Customization: Applies default SEO properties across all pages while allowing overrides for specific routes and content types.

🔗 Application Indexing Control: Prevent staging or admin environments from appearing in search results using noindex flags.

Use Cases

  • E-commerce Product Pages: Configure unique Open Graph images, structured product data, and Twitter Cards for each product listing to improve social sharing and search visibility.
  • Content Marketing Sites: Set up article-specific metadata with JSON-LD markup for authors, publication dates, and categories to qualify for rich snippets in search results.
  • Multi-Language Applications: Define language alternates and locale-specific metadata for international audiences with proper hreflang tags and regional Open Graph properties.
  • Progressive Web Apps: Configure manifest links, theme colors, and app metadata consistently across your SvelteKit application for proper installation behavior.

How to Use It

1. Install the package using your preferred package manager.

npm install -D svelte-seo
# or
yarn add -D svelte-seo
# or
pnpm add -D svelte-seo

2. Import the component inside your Svelte file. You can then place the <SvelteSeo /> component anywhere in your markup. It injects the necessary tags into the <head> of the document.

<script>
  import SvelteSeo from "svelte-seo";
</script>
<SvelteSeo
  title="Dashboard | My App"
  description="View your analytics and account settings."
  canonical="https://myapp.com/dashboard"
/>

3. For pages that require rich social previews and structured data, pass objects to the openGraph, twitter, and jsonLd props. This example sets up a blog post with a summary card for Twitter and article data for Google.

<script>
  import SvelteSeo from "svelte-seo";
  const post = {
    title: "Understanding Svelte Stores",
    summary: "A deep dive into state management in Svelte.",
    slug: "understanding-svelte-stores",
    image: "https://myapp.com/images/stores-banner.jpg"
  };
</script>
<SvelteSeo
  title={post.title}
  description={post.summary}
  openGraph={{
    title: post.title,
    description: post.summary,
    url: `https://myapp.com/blog/${post.slug}`,
    type: "article",
    images: [
      {
        url: post.image,
        width: 800,
        height: 600,
        alt: "Svelte Stores Diagram",
      },
    ],
    site_name: "My Tech Blog",
  }}
  twitter={{
    card: "summary_large_image",
    site: "@mytechblog",
    title: post.title,
    description: post.summary,
    image: post.image,
    imageAlt: "Svelte Stores Diagram",
  }}
  jsonLd={{
    "@context": "https://schema.org",
    "@type": "BlogPosting",
    headline: post.title,
    image: [post.image],
    datePublished: "2023-10-15T08:00:00+08:00",
    author: {
      "@type": "Person",
      name: "Jane Doe"
    }
  }}
/>

4. You can enforce default SEO settings by adding the component to your root layout file (e.g., +layout.svelte in SvelteKit). Properties defined here persist across all pages unless a specific page overrides them.

<!-- src/routes/+layout.svelte -->
<script>
  import SvelteSeo from "svelte-seo";
</script>
<SvelteSeo
  title="My Default Title"
  description="Default description for the application."
  openGraph={{
    site_name: "My App Name",
    type: "website"
  }}
  twitter={{
    site: "@myapp",
    card: "summary"
  }}
/>
<slot />

5. The <SvelteSeo /> component accepts the following SEO properties.

PropertyTypeDescription
titlestringA page title that will appear in search results.
descriptionstringA page description that will appear in search results.
keywordsstringKeywords that give search engines more information about the content of the page.
basestringA default URL and target for all links on a page.
applicationNamestringThe name of the web application that the page represents.
themeColorstringA suggested color that user agents should use to customize the display of the page.
nofollowbooleanPrevents Googlebot from following any links on the page. Default is false.
noindexbooleanPrevents the page from being included in the index. Default is false.
nositelinkssearchboxbooleanOpt out of Google’s Sitelinks search box. Default is false.
notranslatebooleanPrevents Google from translating the page.
canonicalstringThe canonical URL of the page.
ampstringA URL to the AMP version of the webpage.
manifeststringThe URL to a JSON file that tells the browser about your Progressive Web App.
languageAlternatesArrayProvides Google with information about the variations of your content in other languages.
twitter.titlestringThe title of the content, maximum 70 characters.
twitter.descriptionstringA description of the content, maximum 200 characters.
twitter.imagestringThe URL of an image to use in the Twitter card. Images must be less than 5MB.
twitter.imageAltstringA text description of the image for visually impaired users. Max 420 characters.
twitter.cardstringThe type of Twitter card: summary, summary_large_image, player, or app.
twitter.sitestringThe @username of the website.
twitter.creatorstringThe @username of the content creator.
twitter.playerstringThe HTTPS URL of the player iframe.
twitter.playerWidthstringThe width of the iframe in pixels.
twitter.playerHeightstringThe height of the iframe in pixels.
twitter.playerStreamstringThe URL to the raw video or audio stream.
twitter.appNameIphonestringThe name of your iPhone app.
twitter.appUrlIphonestringThe custom URL scheme for your app on iPhone.
twitter.appNameIpadstringThe name of your iPad-optimized app.
twitter.appIdIpadstringYour app’s ID in the iTunes App Store.
twitter.appNameGoogleplaystringThe name of your Android app.
twitter.appIdGoogleplaystringYour app’s ID in the Google Play Store.
twitter.appUrlGoogleplaystringThe custom URL scheme for your app on Google Play.
facebook.appIdstringA unique number that identifies your app (Facebook App ID).
openGraph.titlestringThe title of your object as it should appear within the graph.
openGraph.typestringThe type of your object (e.g., “video.movie”).
openGraph.urlstringThe canonical URL of your object used as its permanent ID.
openGraph.audiostringAn audio file to accompany the content.
openGraph.audioSecure_urlstringAn alternate URL to use if the webpage requires HTTPS.
openGraph.audioTypestringThe MIME type for the audio.
openGraph.descriptionstringA one- or two-sentence description of your object.
openGraph.determinerstringThe word that appears before the title, e.g., “the” or “a”.
openGraph.localestringThe locale of the content, e.g., “en_US”.
openGraph.localeAlternatestring[]Alternate locales for the content.
openGraph.site_namestringThe name of the website where the content is hosted.
openGraph.imagesArrayProperties about images related to the web page.
openGraph.videosObjectProperties about videos related to the web page.
openGraph.musicObjectOpenGraph for music files.
openGraph.movieObjectOpenGraph for a movie.
openGraph.articleObjectOpenGraph for an article.
openGraph.bookObjectOpenGraph for a book.
openGraph.profileObjectOpenGraph for a profile.
jsonLdObjectJSON-LD structured data object.

Related Resources

  • Next SEO: Manages meta tags and structured data for Next.js applications with similar configuration patterns.
  • Svelte Meta Tags: Handles meta tag injection in Svelte with a different API approach.
  • React Helmet: Controls document head elements in React applications with dynamic updates.

FAQs

Q: Can I set different SEO properties for each page in SvelteKit?
A: Yes. Place the SvelteSeo component in individual page files with specific properties. These override any defaults you set in layout files. Each route can have unique metadata.

Q: How do I test that my Open Graph tags work correctly?
A: Use the Facebook Sharing Debugger at developers.facebook.com/tools/debug or the Twitter Card Validator. These tools show exactly how your pages will appear when shared and report any configuration errors.

Q: Does this package work with static site generation in SvelteKit?
A: Yes. The meta tags render during the build process when you use static adapter settings. The generated HTML includes all configured metadata without client-side JavaScript execution.

Q: Can I use multiple JSON-LD schemas on the same page?
A: Yes. Create multiple SvelteSeo components with different jsonLd objects or combine multiple schema types in a single object using an array structure at the root level.

Q: What happens if I set both default and page-specific values for the same property?
A: The page-specific value takes precedence. When you declare a property in a page component, it replaces the default value from your layout entirely rather than merging with it.

Artur Khusaenov

Artur Khusaenov

Leave a Reply

Your email address will not be published. Required fields are marked *