**Outrank**
Get traffic and outrank competitors with Backlinks & SEO-optimized content while you sleep! I've been keeping a close eye on this new tool and it seems to be gaining a lot of traction and delivering great results. [Try it now!](https://outrank.so/?via=next-seo)
[](https://outrank.so/?via=next-seo)
**Have you seen the new Next.js newsletter?**
[
](https://dub.sh/nextjsweekly)
**Other Useful Tools**
- [SEObot - fully autonomous «SEO Robot» with AI agents](https://seobotai.com/?ref=next-seo)
- [dub](https://dub.co/?utm_source=next-seo&utm_medium=social&utm_campaign=next-seo) recently launched a useful Free UTM builder! You can use it [here](https://dub.sh/iKTxs7b)
# Next SEO

Next SEO is a plugin that makes managing your SEO easier in Next.js projects.
Pull requests are very welcome. Also make sure to check out the issues for feature requests if you are
looking for inspiration on what to add.
**Feel like supporting this free plugin?**
It takes a lot of time to maintain an open source project so any small contribution is greatly appreciated.
Coffee fuels coding ☕️
[next-seo.wallet](https://unstoppabledomains.com/d/next-seo.wallet) (ERC20 & SOL)
**Note on app directory**
This note is only relevant if using the `app` directory.
For standard meta data (e.g., ,
Simple Usage
> ); export default Page; ``` But `NextSeo` gives you many more options that you can add. See below for a typical example of a page. **Typical page example:** ```jsx const Page = () => ( <>SEO Added to Page
> ); export default Page; ``` **A note on Twitter Tags** Props `cardType`, `site`, `handle` are equivalent to `twitter:card`, `twitter:site`, `twitter:creator`. Documentation can be found [here](https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/summary). Twitter will read the `og:title`, `og:image` and `og:description` tags for their card. `next-seo` omits `twitter:title`, `twitter:image` and `twitter:description` to avoid duplication. Some tools may report this as an error. See [Issue #14](https://github.com/garmeeh/next-seo/issues/14) ### Default SEO Configuration `NextSeo` enables you to set some default SEO properties that will appear on all pages without needing to include anything on them. You can also override these on a page-by-page basis if needed. To achieve this, you will need to create a custom ````ts import { DefaultSeoProps } from 'next-seo'; const config: DefaultSeoProps = { openGraph: { type: 'website', locale: 'en_IE', url: 'https://www.url.ie/', siteName: 'SiteName', }, twitter: { handle: '@handle', site: '@site', cardType: 'summary_large_image', }, }; export default config; ```
This page is no indexed
> ); export default Page; /* */ ``` #### dangerouslySetAllPagesToNoIndex It has the prefix `dangerously` because it will `noindex` all pages. As this is an SEO plugin, that is kinda dangerous action. It is **not** bad to use this. Just please be sure you want to `noindex` **EVERY** page. You can still override this at a page level if you have a use case to `index` a page. This can be done by setting `noindex: false`. The only way to unset this is by removing the prop from the `DefaultSeo` in your custom `This page is not followed
> ); export default Page; /* */ ``` #### dangerouslySetAllPagesToNoFollow It has the prefix of `dangerously` because it will `nofollow` all pages. As this is an SEO plugin, that is kinda dangerous action. It is **not** bad to use this. Just please be sure you want to `nofollow` **EVERY** page. You can still override this at a page level if you have a use case to `follow` a page. This can be done by setting `nofollow: false`. The only way to unset this, is by removing the prop from the `DefaultSeo` in your custom `Additional robots props in Next-SEO!!
> ); export default Page; /* */ ``` **Available properties** | Property | Type | Description | | ------------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `noarchive` | boolean | Do not show a [cached link](https://support.google.com/websearch/answer/1687222) in search results. | | `nosnippet` | boolean | Do not show a text snippet or video preview in the search results for this page. | | `max-snippet` | number | Use a maximum of [number] characters as a textual snippet for this search result. [Read more](https://developers.google.com/search/reference/robots_meta_tag?hl=en-GB#directives) | | `max-image-preview` | 'none','standard','large' | Set the maximum size of an image preview for this page in a search results. | | `max-video-preview` | number | Use a maximum of [number] seconds as a video snippet for videos on this page in search results. [Read more](https://developers.google.com/search/reference/robots_meta_tag?hl=en-GB#directives) | | `notranslate` | boolean | Do not offer translation of this page in search results. | | `noimageindex` | boolean | Do not index images on this page. | | `unavailable_after` | string | Do not show this page in search results after the specified date/time. The date/time must be specified in a widely adopted format including, but not limited to RFC 822, RFC 850, and ISO 8601. | For more reference about the `X-Robots-Tag` visit [Google Search Central - Control Crawling and Indexing](https://developers.google.com/search/reference/robots_meta_tag?hl=en-GB#directives) #### Twitter Twitter will read the `og:title`, `og:image` and `og:description` tags for their card, this is why `next-seo` omits `twitter:title`, `twitter:image` and `twitter:description` so not to duplicate. Some tools may report this as an error. See [Issue #14](https://github.com/garmeeh/next-seo/issues/14) #### Facebook ```jsx 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 regarding this can be found in Facebook's [documentation](https://developers.facebook.com/docs/sharing/webmasters/) #### Canonical URL Add this on a page-per-page basis when you want to consolidate duplicate URLs. ```js canonical = 'https://www.canonical.ie/'; ``` #### Alternate This link relation is used to indicate a relation between a desktop and a mobile website to search engines. Example: ```jsx mobileAlternate={{ media: 'only screen and (max-width: 640px)', href: 'https://m.canonical.ie', }} ``` ```jsx 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 covered in the `config` and should be used instead of `children` prop. `content` is required. Then either `name`, `property` or `httpEquiv`. (Only one on each) Example: ```js additionalMetaTags={[{ property: 'dc:creator', content: 'Jane Doe' }, { name: 'application-name', content: 'NextSeo' }, { httpEquiv: 'x-ua-compatible', content: 'IE=edge; chrome=1' }]} ``` Invalid Examples: These are invalid as they contain more than one of `name`, `property` and `httpEquiv` on the same entry. ```js additionalMetaTags={[{ property: 'dc:creator', name: 'dc:creator', content: 'Jane Doe' }, { property: 'application-name', httpEquiv: 'application-name', content: 'NextSeo' }]} ``` One thing to note on this is that it currently only supports unique tags unless you use the `keyOverride` prop to provide a unique [key](https://reactjs.org/docs/lists-and-keys.html#keys) to each additional meta tag. The default behaviour (without a `keyOverride` prop) is to render one tag per unique `name` / `property` / `httpEquiv`. The last one defined will be rendered. For example, if you pass 2 tags with the same `property`: ```js additionalMetaTags={[{ property: 'dc:creator', content: 'Joe Bloggs' }, { property: 'dc:creator', content: 'Jane Doe' }]} ``` it will result in this being rendered: ```html ``` Providing an additional `keyOverride` property like this: ```js additionalMetaTags={[{ property: 'dc:creator', content: 'Joe Bloggs', keyOverride: 'creator1', }, { property: 'dc:creator', content: 'Jane Doe', keyOverride: 'creator2', }]} ``` results in the correct HTML being rendered: ```html ``` #### 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: ```js 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: '/manifest.json' }, { rel: 'preload', href: 'https://www.test.ie/font/sample-font.woof2', as: 'font', type: 'font/woff2', crossOrigin: 'anonymous' } ]} ``` it will result in this being rendered: ```html ``` ## Open Graph For the full specification please check outBasic
> ); export default Page; ``` **Note** Multiple images are available from next.js version `7.0.0-canary.0` For versions `6.0.0` - `7.0.0-canary.0` you just need to supply a single item array: ```js images: [ { url: 'https://www.example.ie/og-image-01.jpg', width: 800, height: 600, alt: 'Og Image Alt', }, ], ``` Supplying multiple images will not break anything, but only one will be added to the head. #### Video Full info on [http://ogp.me/](http://ogp.me/#type_video) ```jsx const Page = () => ( <>Article
> ); export default Page; ``` **Note** Multiple images, authors, and tags are available from next.js version `7.0.0-canary.0` For versions `6.0.0` - `7.0.0-canary.0` you just need to supply a single item array: `images:` ```js images: [ { url: 'https://www.example.ie/og-image-01.jpg', width: 800, height: 600, alt: 'Og Image Alt', }, ], ``` `authors:` ```js authors: [ 'https://www.example.com/authors/@firstnameA-lastnameA', ], ``` `tags:` ```js tags: ['Tag A'], ``` Supplying multiple of any of the above will not break anything, but only one will be added to the head. #### Book ```jsx const Page = () => ( <>Book
> ); export default Page; ``` **Note** Multiple images, authors, and tags are available from next.js version `7.0.0-canary.0` For versions `6.0.0` - `7.0.0-canary.0` you just need to supply a single item array: `images:` ```js images: [ { url: 'https://www.example.ie/og-image-01.jpg', width: 800, height: 600, alt: 'Og Image Alt', }, ], ``` `authors:` ```js authors: [ 'https://www.example.com/authors/@firstnameA-lastnameA', ], ``` `tags:` ```js tags: ['Tag A'], ``` Supplying multiple of any of the above will not break anything, but only one will be added to the head. #### Profile ```jsx const Page = () => ( <>Profile
> ); export default Page; ``` **Note** Multiple images are available from next.js version `7.0.0-canary.0` For versions `6.0.0` - `7.0.0-canary.0` you just need to supply a single item array: ```js images: [ { url: 'https://www.example.ie/og-image-01.jpg', width: 800, height: 600, alt: 'Og Image Alt', }, ], ``` Supplying multiple images will not break anything, but only one will be added to the head. ## JSON-LD Next SEO now has the ability to set JSON-LD a form of structured data. Structured data is a standardized format for providing information about a page and classifying the page content. Google has excellent content on JSON-LD -> [HERE](https://developers.google.com/search/docs/data-types/article) **If using the app directory then please ensure to add `useAppDir={true}` prop and that you are using the component in the `page.js`** Below you will find a very basic page implementing each of the available JSON-LD types: - [Article](#article-1) - [Breadcrumb](#breadcrumb) - [Blog](#blog) - [Campground](#campground) - [Recipe](#recipe) - [Sitelinks Search Box](#sitelinks-search-box) - [Course](#course) - [Dataset](#dataset) - [Corporate Contact](#corporate-contact) - [FAQ Page](#faq-page) - [How-to](#how-to) - [Job Posting](#job-posting) - [Local Business](#local-business) - [Product](#product) - [Social Profile](#social-profile) - [News Article](#news-article) - [Park](#park) Pull requests are very welcome to add any from the list [found here](https://developers.google.com/search/docs/data-types/article) #### JSON-LD Security Just a quick note on security. To get JSON-LD onto the page it needs to be in a script tag. `next-seo` achieves this by using a script tag with `dangerouslySetInnerHTML`. So if passing anything directly from a URL to one of the components below please ensure you sanitize it first if needed. View `toJson.tsx` for implementation detail. #### Handling multiple instances If your page requires multiple instances of a given JSON-LD component, you can specify unique `keyOverride` properties, and `next-seo` will handle the rest. This comes in handy for blog rolls, search results, and overview pages. Please fully research when you should and shouldn't add multiple instances of JSON-LD. ```jsx