-
-
Notifications
You must be signed in to change notification settings - Fork 801
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
Improved seo docs page #297
base: main
Are you sure you want to change the base?
Conversation
Added Other Pages Meta Tags & Structured data and Schema markup
Added Other Pages Meta Tags & Structured data and Schema markup
Update seo.md
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work @NeroxTGC , thanks for this!
I think this generaly makes sense and looks good -> I left some comments, but nothing major I believe, let's take care of those and we can merge!
:::note[Important] | ||
By default, all pages will acquire the main Landing Page meta tags. You can set custom meta tags for each page using `react-helmet-async`. | ||
::: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can probably just take this out of :::note, make it normal text. I understand it was meant to emphasize it as the most important thing here, which it is, but it actually fits well into the normal flow of the reading while :::notes break it a bit.
By default, all pages will acquire the main Landing Page meta tags. You can set custom meta tags for each page using `react-helmet-async`. | ||
::: | ||
|
||
[React Helmet Async](https://github.com/staylor/react-helmet-async) is a thread-safe fork of React Helmet, serving as the React equivalent to [Next SEO](https://github.com/garmeeh/next-seo) for Next.js applications. If you're familiar with Next SEO, you'll find React Helmet Async follows similar patterns for managing meta tags in React applications. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While this is great for people who know Next, it is not great for people who don't, as reference to next-seo doesn't mean much to them.
We want to assume as little of specific konweldge by the reader (like knowing next and next-seo), so it would be better if we wrote this in a different way.
I propose something like this:
React Helmet Async is a React library that allows you to modify <head>
directly from your React component, in a dynamic fashion. Therefore, it can also be used to set meta tags.
:::note
Since Wasp is SPA, React Helmet Async updates <head>
via client-side JS after initial serve, meaning that web crawlers that don't evaluate JS won't pick up the modifications to the <head>
you did.
:::
```bash | ||
# Using npm | ||
npm install react-helmet-async | ||
|
||
# Using yarn | ||
yarn add react-helmet-async | ||
|
||
# Using pnpm | ||
pnpm add react-helmet-async | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is enough to just show npm, yarn and pnpm users will find their way.
|
||
```jsx | ||
//Add the react-helmet-async import | ||
import { Helmet, HelmetProvider } from 'react-helmet-async'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Helmet import is redundant here, just HelmetProvider is enough.
|
||
//Wrap the main App component | ||
export default function App() { | ||
return ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return ( | |
return ( |
|
||
```jsx {6-33) | ||
//... | ||
import { Helmet, HelmetProvider } from 'react-helmet-async'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HelmetProvider import is redudnant here.
``` | ||
|
||
:::tip[Good SEO practice] | ||
There are certain pages that it is good SEO practice not to index. They are divided into two groups: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are certain pages that it is good SEO practice not to index. They are divided into two groups: | |
There are certain pages that it is good SEO practice not to index, for example: |
|
||
- Pages that do not add value (login, signup, password reset, ....). | ||
- Legal pages: Privacy Policy, Cookies Policy, Terms and Conditions. | ||
- Any other page that you consider should not be indexed (imagine that you create a page exclusively for ADS campaigns and for sure you don't want to receive organic traffic on it!). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Any other page that you consider should not be indexed (imagine that you create a page exclusively for ADS campaigns and for sure you don't want to receive organic traffic on it!). | |
- Situational pages (e.g. page made for a specific campaign). |
- [Google rich results test](https://search.google.com/test/rich-results) | ||
- [Schema validator](https://validator.schema.org/) | ||
|
||
This means you **do not** need to rely on a separate app or framework to serve your pages for SEO purposes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line is not needed I think, no need to emphasize this.
## Structured data and Schema markup | ||
|
||
:::note[Tip] | ||
Crawlers do all the work of analyzing and understanding the content of your pages, and they will thank you if you include structured data to help them understand what your content is about!🤗. | ||
::: | ||
|
||
You can add structured data for each page. | ||
|
||
```jsx {14-22} | ||
//... | ||
import { Helmet, HelmetProvider } from 'react-helmet-async'; | ||
|
||
export function MyCustomPage() { | ||
return ( | ||
<div> | ||
<Helmet> | ||
<title>My Custom Page Title</title> | ||
<meta | ||
name='description' | ||
content='This is the meta description of my page.'/> | ||
<link rel='canonical' href='https://example.com/my-custom-page' /> | ||
//... | ||
|
||
<script type='application/ld+json'>{` | ||
{ | ||
"@context": "https://schema.org", | ||
"@type": "SoftwareApplication", | ||
"name": "title", | ||
"url": "https://yoururl.com", | ||
"description": "Description", | ||
} | ||
} | ||
`} </script> | ||
|
||
</Helmet> | ||
//... | ||
``` | ||
|
||
|
||
These resources provide the information needed to get the most out of structured data: | ||
- [Introduction to structured data markup](https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data) | ||
- [General structured data guidelines](https://developers.google.com/search/docs/appearance/structured-data/sd-policies) | ||
|
||
After you have a small notion about them, you can go deeper by adding custom functions depending on your app (FAQs, Rating, Review, Software Application...): | ||
- [ALL structured data functions](https://developers.google.com/search/docs/appearance/structured-data/search-gallery) | ||
|
||
To ensure that they are valid: | ||
- [Google rich results test](https://search.google.com/test/rich-results) | ||
- [Schema validator](https://validator.schema.org/) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This dive intro structured data might and schema markup might be a bit beyond the scope of this docs. That said, we can provide a sentence or two about it + a single link, or max two, where they can read about them. Meaning we can significantly shorten this part and throw out the code example!
@Martinsos I finished updating the document with your suggested changes. If you like, check it one last time. I've also created a |
Description
Contributor Checklist