# Apply SEO best practices

This guide describes how you can implement SEO best practices in Appfarm. It is not a general guide to SEO. If you are looking for a grounding in SEO, see this [guide from Ahrefs](https://ahrefs.com/seo).

For an app to be accessible by search engines and the broader public it must be available with [unauthenticated access](https://docs.appfarm.io/how-to/authentication-and-access-control/unauthenticated-access).

The following topics are addressed in the guide:

* Set the title tag for each view
* Set a meta description for each view
* Set a canonical URL for each view (only if you have a custom domain)
* Optimize internal linking
* Optimize images
* Inform search engines

As Google is the biggest referrer of search traffic links are provided to Google search documentation for more information, where relevant.

{% hint style="info" %}
**Canonical URLs**

If you have added a [custom domain](https://docs.appfarm.io/how-to/security-testing-and-deployment/add-a-custom-domain) to your solution your app can be accessed using two hostnames; your custom domain and the default \[solution].appfarm.app URL. Set a canonical URL for each view in your app using your custom domain to send a strong signal to Google that this is the URL that should be shown in search results.

Further reading: [What is URL canonicalization? ](https://developers.google.com/search/docs/crawling-indexing/canonicalization)
{% endhint %}

### Use On App Load to inject HTML tags

Typically you’ll want to set a meta description and potentially a canonical URL per page (view). These tags need to be added into the app’s HTML. Use the [On App Load](https://docs.appfarm.io/reference/platform-concepts/event-handlers#automatic-events) event handler to trigger an action and use the [Run Code action node](https://docs.appfarm.io/library/action-nodes/run-code) to inject the tags. Example code is provided below. You can then use the [On View Load](https://docs.appfarm.io/reference/platform-concepts/event-handlers) event handler to update them.

{% code title="Example code" %}

```javascript
// Create and append empty meta description
const metaTag = document.createElement("meta");
metaTag.name = "description";
document.head.appendChild(metaTag);

// Create and append empty canonical URL
const linkTag = document.createElement("link");
linkTag.rel = "canonical";
document.head.appendChild(linkTag);

resolve();
```

{% endcode %}

### Use On View Load to update HTML tags

To set unique content in the HTML tags for each view, use the [On View Load](https://docs.appfarm.io/reference/platform-concepts/event-handlers) event handler to trigger an action. You can use the same action for each view and use logic to insert the appropriate content for that view.

To set a page’s `<title>` tag, update the [built-in App Variable](https://docs.appfarm.io/reference/apps/data/app-variables#built-in-app-variables) **Document Title**.

To update the meta description and canonical URL tags, use the [Run Code action node](https://docs.appfarm.io/library/action-nodes/run-code). Example code is provided below.

{% code title="Example code" %}

```javascript
// Update the meta description
let metaDescription = document.querySelector('meta[name="description"]');
metaDescription["content"] = "Enter your meta description for this view";

// Update the canonical URL
const path = window.location.pathname;
let canonicalUrl = document.querySelector('link[rel="canonical"]');
canonicalUrl["href"] = `https://your.customdomain.com${path}`;

resolve();
```

{% endcode %}

By using On View Load to trigger updates to the HTML tags, you ensure that they are updated whether a user (or Google Crawler) arrives at a page directly or by navigating inside the app.

Further reading: [Best practices for title tags](https://developers.google.com/search/docs/appearance/title-link), [Best practices for creating quality meta descriptions](https://developers.google.com/search/docs/appearance/snippet#meta-descriptions)

### Optimize internal linking

When you use the [Navigate action node](https://docs.appfarm.io/library/action-nodes/navigate) to navigate to the default view, select the **Navigate to Root** checkbox.

By navigating to the root when the default view is to be loaded, the URL path for that view will always be the app root. If you instead use the **View** property to select the view, the [view’s URL Path Key](https://docs.appfarm.io/reference/apps/ui/views#general-properties) is added to the URL and this results in two different URLs displaying the same content.

Restricting it to the root means that search engines (and users) will only see and share one URL for that content, focusing the search ranking on one primary URL.

### Optimize images

If you have an image-heavy page, consider using the **Lazy Load Image** and **Responsive Image** properties on the the [Image UI component](https://docs.appfarm.io/library/ui-components/image). These improve page performance which is a search ranking factor.

Additionally, you should use descriptive file names for your images and include descriptive alt text.

Further reading: [Google image SEO best practices](https://developers.google.com/search/docs/appearance/google-images)

### Inform search engines

The easiest way to inform search engines about your app is ask them to crawl the URLs. For example, you can [ask Google to crawl your URLs](https://developers.google.com/search/docs/crawling-indexing/ask-google-to-recrawl) using Google Search Console.

If you need to verify ownership of the property in Google Search Console, you can select the HTML tag method and add the provided meta tag as a [custom header tag](https://docs.appfarm.io/reference/configuration/environments#custom-header-tags) in the Production environment.

Another way to inform search engines is to submit a sitemap, but depending on the nature of your app you may not need a sitemap. In [Google’s documentation on sitemaps](https://developers.google.com/search/docs/crawling-indexing/sitemaps/overview#do-i-need-a-sitemap) they state that you might **not** need a sitemap if:

* Your site is small (Google classifies a site with 500 pages or fewer as small)
* Your site is comprehensively linked internally
* You don't have many media files (video, image) or news pages that you want to show in search results

If you determine that you require a sitemap, you can generate an XML sitemap and add it as a [.well-known directory entry](https://docs.appfarm.io/reference/configuration/environments#other) in the Production environment. You must then [submit it directly within Google Search Console](https://support.google.com/webmasters/answer/7451001#zippy=%2Csubmit-a-sitemap).
