CodingGarden / listd

listd is a Full Stack App that will allow users to create, share and watch lists of YouTube channels. This app is being built LIVE on Twitch https://twitch.tv/codinggarden
https://twitch.tv/codinggarden
MIT License
190 stars 53 forks source link

Create SEO component to easily set title / meta information #78

Closed Limeoats closed 1 year ago

Limeoats commented 1 year ago

Created an SEO component to easily set the page title / meta information for each page in the application.

What type of Pull Request is this?

Delete all options except for the one that applies

What is the current behavior?

You would have to manually work with the <svelte:head> on each page to set a title.

Issue Number: N/A

What is the new behavior?

omar2205 commented 1 year ago

Can you turn it into a store? Then we can update the store in pages (or components if we need to)

w3cj commented 1 year ago

Can you turn it into a store? Then we can update the store in pages (or components if we need to)

Yeah I second this. I think for certain pages it will make sense to import the Seo component and specify the props directly, but for convenience it will be nice to just import a store and set the title / description there.

Limeoats commented 1 year ago

So for the title and description to be injected into the <head> of the page, it needs to be set within the <svelte:head> tag. Sure, we can store the page title / description in a store for easier updating, but it still needs to be put into that <svelte:head> somewhere. That's where the Seo component comes in since you just pop that onto a page and it handles it for you.

The Seo component could pull the title and description from the store and set them that way (or through props), but you'd still need to put the Seo component onto each page either way.

I'm fairly new to Svelte so I might be missing something!

paoloricciuti commented 1 year ago

So for the title and description to be injected into the <head> of the page, it needs to be set within the <svelte:head> tag. Sure, we can store the page title / description in a store for easier updating, but it still needs to be put into that <svelte:head> somewhere. That's where the Seo component comes in since you just pop that onto a page and it handles it for you.

The Seo component could pull the title and description from the store and set them that way (or through props), but you'd still need to put the Seo component onto each page either way.

I'm fairly new to Svelte so I might be missing something!

What you can do is use in the root layout and pull the information from the store. Than if you import the store inside a page and set the values there the layout would reflect that information.

Honestly tho I feel like the SEO component would be clearer and less bug prone.

omar2205 commented 1 year ago

You will just put the <Seo /> or <svelte:head> in the main root layout.

// src/lib/SeoStore.ts or // src/lib/MainStore.ts
import { writable } from 'svelte/store'

export const Seo = writable({
  title: 'Home'
})
<!-- +layout.svelte -->
<svelte:head>
  <title>{$Seo.title || 'Home Page'}</title>
</svelte:head>

Honestly tho I feel like the SEO component would be clearer and less bug prone.

Why do you think this is prone to bugs?

Limeoats commented 1 year ago

So I think I was able to accomplish the best of both methods with my latest commit. The title and description are now in a store, so those values can be updated from any component or page. I put an instance of the Seo component on the root layout so it'll automatically pull in those values. However, if you want to, you can still use the Seo component directly and set the props.

I used both methods to show them working on the two existing pages in the app. The homepage sets the values directly in the store and the onboarding page uses the Seo component to do so.

I recognize that there isn't much purpose to keep the Seo component in its current state since this can all be done directly with the store and <svelte:head> in the root layout, but there might be future use cases where you'll want logic associated with some SEO-related stuff, in which case it might be nice to have that contained in a component that can be affected by props. I'm happy to remove it if it's found to be unnecessary, though.

paoloricciuti commented 1 year ago

You will just put the <Seo /> or <svelte:head> in the main root layout.

// src/lib/SeoStore.ts or // src/lib/MainStore.ts
import { writable } from 'svelte/store'

export const Seo = writable({
  title: 'Home'
})
<!-- +layout.svelte -->
<svelte:head>
  <title>{$Seo.title || 'Home Page'}</title>
</svelte:head>

Honestly tho I feel like the SEO component would be clearer and less bug prone.

Why do you think this is prone to bugs?

Maybe it's just me but given that the SEO tags are part of the markup I would prefer to have them as a component.

But now that I think about it you can't have more than one svelte:head inside a page so if you want to update it inside a layout and than override it in a page you couldn't do it with the component but it works fine with the store.

omar2205 commented 1 year ago

@Limeoats Please add/update these tags. og:image is a placeholder until CJ decides listd's branding.

<title>listd - Create, share and watch lists of YouTube channels</title>
<meta name="description" content="listd is a Full Stack App allowing users to create, share and watch lists of YouTube channels. Whether you want to discover new content, organize your favorites or share your opinions, listd is the app for you." />
<meta name="keywords" content="listd, youtube, channels, lists, app" />

<meta property="og:title" content="listd - Create, share and watch lists of YouTube channels" />
<meta property="og:description" content="listd is a Full Stack App allowing users to create, share and watch lists of YouTube channels. Whether you want to discover new content, organize your favorites or share your opinions, listd is the app for you." />
<meta property="og:image" content="https://user-images.githubusercontent.com/1373867/221797903-42b3a12d-7d63-4284-b17a-83e2721a5d83.png" />
<meta property="og:url" content="https://listd.tv" />

<meta property="twitter:card" content="https://user-images.githubusercontent.com/1373867/221797903-42b3a12d-7d63-4284-b17a-83e2721a5d83.png">
<meta property="twitter:url" content="https://listd.tv">
<meta property="twitter:title" content="listd - Create, share and watch lists of YouTube channels">
<meta property="twitter:description" content="listd is a Full Stack App allowing users to create, share and watch lists of YouTube channels. Whether you want to discover new content, organize your favorites or share your opinions, listd is the app for you.">
<meta property="twitter:image" content="https://user-images.githubusercontent.com/1373867/221797903-42b3a12d-7d63-4284-b17a-83e2721a5d83.png">

Obviously, duplicated items share the same store value or variables.

Limeoats commented 1 year ago

@omar2205 Is it best practice to store all of that data in the store? Most of that will never be modified by other components / pages so I would think it would be hardcoded into the Seo component, and then description, title, og:title, og:description, twitter:title, and twitter:description would pull the data from the store (sharing the same data as you mentioned). Do you agree?

omar2205 commented 1 year ago

@Limeoats We will need to update these with a list’s image, title, and description in the future. You can just hard code them for now and maybe add a note/todo.

Limeoats commented 1 year ago

Ok, I added the extra fields. More can be included in the future by just adding them to the Seo component.

omar2205 commented 1 year ago

lgtm

omar2205 commented 1 year ago

finally the \ saga is merged.