## Intro [SEO](https://en.wikipedia.org/wiki/Search_engine_optimization) (Search engine optimization) is to make web content readable and indexable by search engines such as [Google](https://google.com). Because app built with go-app are Go binaries loaded in the web browser and their content is generated dynamically on the client-side, it is tricky for search engines to crawl and index apps content. Go-app is solving that issue by prerendering components on the server-side before including the generated HTML markup into requested pages. ## Prerendering Prerendering is about converting a [component](/components) to its plain HTML representation. On the server-side, when the [Handler](/reference#Handler) receives a page request, it creates an instance of the component associated with the requested URL, generates its HTML representation, and includes it on the page. For a simple Hello world component: ```go type hello struct { app.Compo } func (h *hello) Render() app.UI { return app.H1().Text("Hello World!") } ``` The generated page will look like the following code: ```html

Hello World!

Loading...

``` ### Customizing prerendering Like on the client-side, a component might require further initializations. Launching additional instructions is done by implementing the [PreRender](/reference#PreRenderer) interface. Here is a Hello example that gets the username from an URL parameter: ```go type hello struct { app.Compo name string } func (h *hello) OnPreRender(ctx app.Context) { username := ctx.Page.URL().Query().Get("username") h.name = username } func (h *hello) Render() app.UI { return app.H1().Text("Hello " + h.name) } ``` ### Customizing page metadata An essential step for a good SEO is to have meta tags, such as page title, well-formed. Page metadata can be set from the `OnPreRender` [Context](/reference#Context) argument. Context contains a [page](/reference#Page) field to set page metadata. Here is an example that sets the page title and author. ```go func (h *hello) OnPreRender(ctx app.Context) { ctx.Page.SetTitle("A Hello World written with go-app") ctx.Page.SetAuthor("Maxence") } ``` **See the [page reference](/reference#Page) for the detail of customizable metadata**. ### Caching For performance reasons, prerendered pages are cached once generated. The [Handler](/reference#Handler) provides a `PreRenderCache` field that allows customizing the cache behavior. By default, it uses an in-memory [LRU cache]() that keeps cached data for 24 hours with a maximum size of 8MB. Cache behavior can be customized by setting the PreRendering cache to [another LRU cache](/reference#NewPreRenderLRUCache) with different values: ```go h := app.Handler{ Name: "Hello world", PreRenderCache: app.NewPreRenderLRUCache(100*100000, time.Hour), // 10MB/1hour } ``` Or any other cache that satisfies the [PreRenderCache](/reference#PreRenderCache) interface: ```go type PreRenderCache interface { // Get returns the item at the given path. Get(ctx context.Context, path string) (PreRenderedItem, bool) // Set stored the item at the given path. Set(ctx context.Context, i PreRenderedItem) } ``` You could implement a cache based on Redis or any other datastore. ## Next - [Lifecycle and Updates](/lifecycle) - [Reference](/reference)