-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Define default meta tags, title etc. and have the option to override it #1540
Comments
If think it's a good idea, because, event if we could create an SEO component, there is a little bug, sometimes hydratation generate two |
This comment has been minimized.
This comment has been minimized.
#269 would help quite a bit with making this easier as each page could pass its title to the layout and you would only need the layout to set the title |
With the recent addition of Following is a TypeScript example. In declare namespace App {
interface Locals {}
interface Platform {}
interface Session {}
interface Stuff {
description: string;
}
} In <script context="module" lang="ts">
export const load = () => ({
stuff: {
description: 'Description from page'
}
});
</script> In <script context="module" lang="ts">
export const load = () => ({
stuff: {
description: 'Default description from layout'
}
});
</script>
<script lang="ts">
import { page } from '$app/stores';
</script>
<svelte:head>
<meta name="description" content={$page.stuff.description} />
</svelte:head> Edit: Updated code based on #1540 (comment) |
Yes, I think we can for now and see how well that solves the problem for people. We've also documented it here: https://kit.svelte.dev/docs/seo |
could not follow this example and gave up. Documentation sadly lacking in any detail. |
The example just above seems pretty fleshed out. I'm not sure why you'd be having trouble with it and you haven't given any details as to what you're having difficulty with. I'd suggest that a closed issue is not the correct place to ask for help though and you should ask on Discord, GitHub Discussions, or StackOverflow. The one thing I'd note is that doing |
With |
The question was about an option to "override" but the solution provided here #1540 (comment) (the above comment that people don't seem to like), is the other way around, it's watching a variable and making the layout respond to changes, which is, I guess, the pretty standard way, just thought in SvelteKit things would be done differently, that the child would override its parent. Nope, not today. |
You could just use $page.data like |
Apologies for resurrecting this closed issue, but is returning some arbitrary object properties in the Just my 2c, but this seems like an overly complicated (and frankly, unique) solution to an issue that has been solved time and time again in most of the other (non-svelte) frameworks that i'm sure many incoming svelte developers are familiar with. Having our layout(s) rely on specific object properties to be defined in the response of various Additionally, i think it should be made more clear in the docs that defining ''default'' meta tags in your layout will not work as expected when defining those same tags in your pages. The small blurb about using |
+1 Agreed. As a newbie to SvelteKit I went through all the tutorials and generally accepted advice and it really seemed like I was supposed to put, for example <svelte:head>
<title>Website</title>
</svelte:head> into my root +layout.svelte and then <svelte:head>
<title>Specific Subroute - Website</title>
</svelte:head> Into However when doing it this way, the correct "subroute" title loads for a second, then changes back to the base title after page loading is complete. I'm still not clear on how it's supposed to work -- I guess you should only use
Yes, and the example uses the |
The docs could definitely be improved. Doing SEO feels more straight forward with other frameworks. It seems like the key is to learn how to work with page data, routes/some/path/+page.js export function load() {
return {
pageMeta: {
"title": "Some Page",
"description": "Description of Some Page",
},
};
} routes/+layout.server.js import { ENABLE_ANALYTICS } from "$env/static/private";
export function load() {
return { ENABLE_ANALYTICS };
} routes/+layout.svelte <script>
import { page } from "$app/stores";
let { data } = $props();
let head = $state({});
let siteName = "My Blog";
let author = "My Name";
let defaultKeywords = ["Foo", "Bar"];
let setHead = () => {
if ($page.data.pageMeta.title) {
head.title = $page.data.pageMeta.title + " - " + siteName;
} else {
head.title = siteName;
}
if ($page.data.pageMeta.description) {
head.description = $page.data.pageMeta.description;
} else {
head.description = undefined;
}
if ($page.data.pageMeta.keywords) {
head.keywords = [...defaultKeywords, ...$page.data.pageMeta.keywords || []];
} else {
head.keywords = defaultKeywords;
}
head.author = author;
};
setHead();
$effect(setHead);
</script>
<svelte:head>
<title>{head.title}</title>
{#if head.description}
<meta name="description" content={head.description}>
{/if}
{#if head.keywords}
<meta name="keywords" content={head.keywords.join(" ")}>
{/if}
{#if head.author}
<meta name="author" content={head.author}>
{/if}
{#if data.ENABLE_ANALYTICS == "true"}
<script>do_analytics();</script>
{/if}
</svelte:head> |
I want to define default meta tags, title etc. and have the option to override it per page.
For example: I have 10 generic pages where I just want to use the default ones and then I have 5 pages where I want to set individual meta keywords, description, title etc.
In the app.html I can define those default tags, but if I set new tags via svelte:head it just appends those new tags and doesn't replace the existing ones.
I also tried playing around with __layout.svelte (since this is somehow a root component at the moment) and Context API etc. but this didn't work for me.
At the moment, the only solution I can find is creating a root component (e. g. App.svelte) and every page will import and call it. This root component will then export those meta tags and title and will have default values. Then I remove those tags from the app.html and pass it 1x from the root component with svelte:head
But this seems to be cumbersome and would mean that in my case, I have to update more than 100 pages.
Is there a better way of doing that?
the easiest way of doing it would be to have an "override" mode for svelte:head:
edit: there is also a realted Svelte issue: sveltejs/svelte#4990
It would also be a nice solution to have some sort of named slots here (in the app.html, the __layout.svelte or somewhere else).
Using a store (https://github.com/svelte-society/sveltesociety-2021/blob/main/src/lib/stores/metatags.ts) can also be a solution, but the "override" solution seems to be easier to read and write.
The text was updated successfully, but these errors were encountered: