> For the complete documentation index, see [llms.txt](https://docs.fact-finder.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fact-finder.com/webcomponents-overview/web-components-4.x./guides/advanced/server-side-rendering.md).

# Server Side Rendering

Pre-render search records server-side and hydrate them with Web Components.

Server Side Rendering (SSR) is a technique which enables pre-rendering a whole page's HTML on the server side before sending it back to the client.

There are a couple of benefits in using this approach:

* HTML content is available to web crawlers for scanning which is important for SEO
* Unified performance, conditioned by the application server, not the user's web browser

With SSR, an application server responds with a page that is viewable but not yet functional. Then the client side part of the application renders the HTML once again making it fully functional for the user.

Opposite to SSR stands CSR (client side rendering) which is the standard way of running web applications. With this approach the server returns raw HTML, often containing framework-specific tags, which should not be visible to the user. Then the client side application renders the fully viewable page.

However, the rendered result is not available to scanning bots as they only scan the HTML returned by the server. This might be an issue where an application renders business critical content (e.g. an e-shop rendering products) and has the effect that search engines will never index such applications properly as they have no chance to detect what the real and full page content is.

To ensure that users can properly promote their websites on the Internet, Web Components' `ff-record-list` has been enhanced with SSR capability.

{% stepper %}
{% step %}

### Server side: Send a search request

In order to render records on the server side, your application needs to send a **search** request to FactFinder to get product data to work with.
{% endstep %}

{% step %}

### Server side: Pre-render the records

With the response from the request above, you need to prepare a specific view object representing a page to be output.

At this stage, records fetched from FactFinder should be converted into `ff-record` elements. To do so, you may want to use a template engine which hydrates raw templates with real data.

Web Components uses the mustache.js [template engine](file:///documentation/4.x/template-engine), so it may be the easiest to use its server side counterpart.

Example libraries (the whole list of libraries can be found at [mustache.github.io](https://mustache.github.io/)):

* java: <https://github.com/spullara/mustache.java>
* PHP: <https://github.com/bobthecow/mustache.php>

{% hint style="info" %}
You are not just limited to mustache. You can use any template engine your platform supports. The advantage of using mustache here is that you can use the same templates as in Web Components.
{% endhint %}
{% endstep %}

{% step %}

### Server side: Send the response

The response to the browser contains the pre-rendered HTML and the raw response ready to be used by Web Components.

The most convenient way to make the response available to use by Web Components is to store it as JSON in a variable.

```html
<script>
    const rawResponse = JSON.parse(RESPONSE_TEXT);
</script> 
```

{% hint style="info" %}
`RESPONSE_TEXT` in the example above represents the response text received from FactFinder. The way it is passed to a variable depends on the used framework.
{% endhint %}

This step concludes the server side part. It does not exhaust the subject though.

At this point, `ff-record-list` should look the same as if it was rendered on the client side (with the difference of not being fully interactive). It should be considered as a mock and must be replaced with another instance - this time rendered by Web Components.
{% endstep %}

{% step %}

### Client side: Set up the HTML

First, the `ff-record-list` element needs the `ssr` attribute. The pre-rendered `ff-record` elements go directly inside the `ff-record-list` element.

```html
<ff-record-list ssr>
    <!-- Put pre-rendered records here. -->
</ff-record-list>
```

### Record template

As the pre-rendered `ff-record` elements do not contain **mustache.js** data bindings, Web Components cannot use them as a template to render new records. Therefore, the `ff-record` template must be specified separately.

```html
<ff-record-list ssr>
    <template data-role="record">
        <!-- Put the `ff-record` element template here. --->
    </template>
</ff-record-list>
```

See the `ff-record-list` [documentation](file:///api/4.x/ff-record-list#tab=docs) for more details about its template.

### Record insertion point

You can define explicitly at which location records of future searches shall be inserted into `ff-record-list`.

Usually, `ff-record-list` guesses the correct location but in case a server side rendered page produces an *empty result*, there is no information where records shall be inserted, and therefore they will always be added to the very bottom. This may not be the correct location if you have additional custom HTML inside `ff-record-list`.

```html
<ff-record-list ssr>
    <div>Custom HTML before records.</div>
    
    <!-- Pre-rendered records from server-side request. -->
    <ff-record class="someClass">Product title 1</ff-record>
    <ff-record class="someClass">Product title 2</ff-record>
    
    <!-- Always add the insertion marker AFTER the records. -->
    <template data-role="records-insertion-point"></template>
    
    <div>Custom HTML after records.</div>
</ff-record-list>
```

Even though this step is *optional*, it is **recommended** you always specify the insertion point.

{% hint style="warning" %}
Make sure to always place the insertion marker **after** the records or the order in which records are rendered may get compromised.
{% endhint %}

### Example

Here is a schematic example of the complete HTML setup.

```html
<ff-record-list ssr>
    <ff-record class="someClass">Product title 1</ff-record>
    <ff-record class="someClass">Product title 2</ff-record>
    <ff-record class="someClass">Product title 3</ff-record>
    <ff-record class="someClass">Product title 4</ff-record>
    
    <template data-role="records-insertion-point"></template>
    
    <template data-role="record">
        <ff-record class="someClass">{{record.title}}</ff-record>
    </template>
</ff-record-list>
```

{% endstep %}

{% step %}

### Client side: Dispatch the response

After setting up the HTML, the only thing left to do is dispatch the response to Web Components using `dispatchSSR`.

See [Result Dispatcher](file:///api/4.x/core-result-dispatcher) for details regarding this utility.

Dispatching the response via `dispatchSSR` will trigger `ff-record-list` to replace pre-rendered records with the actual ones.

```html
<script type="text/javascript">
    document.addEventListener(`ffCommunicationReady`, ({ factfinder }) => {
        const rawResponse = JSON.parse(RESPONSE_TEXT);
        factfinder.communication.ResultDispatcher.dispatchSSR(rawResponse);
    });
</script>
```

{% endstep %}

{% step %}

### Client side: Do not perform an initial search

Dispatching the raw response replaces the initial search request that is typically triggered through the `search-immediate` attribute on the `ff-communication` element.

```html
<ff-communication
    search-immediate  <!-- Do not use this attribute. -->
></ff-communication>
```

{% endstep %}
{% endstepper %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.fact-finder.com/webcomponents-overview/web-components-4.x./guides/advanced/server-side-rendering.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
