> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mastermindcms.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Examples

> Common MastermindCMS patterns (SSR + API + web components)

## Page skeleton

```html theme={null}
<!doctype html>
<html>
  <head>
    <script src="/msm2.bundle.js"></script>
  </head>
  <body>
    <msm:fragment id="header" path="main/components/navbar.html" />

    <main>
      <msm:if id="isLoggedIn" bean="userServiceImpl" scope="SESSION" test="isLoggedIn">
        <msm:template>
          <msm-navbar></msm-navbar>
        </msm:template>
      </msm:if>
    </main>
  </body>
</html>
```

For client-side calls, initialize one shared instance after the library has loaded:

```js theme={null}
const app = new MSM2.App("wss://example.com");
```

## WebSocket JSON endpoints (overview)

* `/request/json/bean/{INVOKE|UPDATE}`
* `/request/json/repository/{INVOKE|UPDATE}`
* `/request/json/database`

## Backend service call

```js theme={null}
import { callService } from "msm-components/dist/services.js";

const response = await callService(
  "searchManagerServiceImpl", "PROTOTYPE", "search",
  [{ query: { isPublishedForSale: true }, offset: 0, limit: 10 }]
);
const items = response.result?.data?.content ?? [];
```

If the backend method expects a JSON string, pass `JSON.stringify(request)` as its argument.

## Repository and bean operations

```js theme={null}
import { callRepository, updateBean } from "msm-components/dist/services.js";

const categoryResponse = await callRepository("blogCategoryRepository", {
  query: { _id: categoryId }, skip: 0, limit: 1,
});

// Updates values on a bean registered with @Component or @Service.
await updateBean(
  "dummyBean", "PROTOTYPE",
  { description: "Updated description" }
);
```

## React data loading

```jsx theme={null}
import { useEffect, useState } from "react";

const app = new MSM2.App("wss://example.com");

export function ProductList() {
  const [items, setItems] = useState([]);
  useEffect(() => {
    const subscription = app.invokeAndGetJson$(
      "searchManagerServiceImpl", "PROTOTYPE", "search",
      [{ type: "SellerSKU", query: {}, offset: 0, limit: 10 }], null, "USER"
    ).subscribe((response) => setItems(response.result?.data?.content ?? []));
    return () => subscription.unsubscribe();
  }, []);
  return <ul>{items.map((item) => <li key={item.id}>{item.name}</li>)}</ul>;
}
```

## SSR and custom events

```js theme={null}
app.renderPage();
app.renderElement(
  [{ elementId: "cart-container", path: "/components/cart", payload: {} }],
  { userId }
);

const subscription = app.registerJsonWebSocket("jobs", (event) => {
  console.log("Job event", event);
});
```

## Translations and routing

```js theme={null}
import { setLocalesPath, translate, loadManyTranslations } from "msm-components/dist/services.js";
import { routeManager } from "msm-components/dist/services.js";

setLocalesPath("/assets/locales/{{lng}}.json");
document.title = await translate("DashboardTitle");
const texts = await loadManyTranslations("SaveButton", "CancelButton");

routeManager.init("My application");
routeManager.addRoute("/", "home", "HomeTitle");
routeManager.addRoute("/products/:id.html", "product", "ProductTitle");
routeManager.loadRouteByCurrentUrl();
routeManager.navigate("product", "42.html");
```

## Web components

```html theme={null}
<msc-header></msc-header>
<msm-button type="OUTLINE" variant="emphasis" href="/catalog">
  Open catalog
</msm-button>
<msm-login-form></msm-login-form>
```

## Authentication

```js theme={null}
MSM2.App.AuthHelper.authenticate$(
  "/api/v1/authenticate", "username=user@example.com&password=secret"
).subscribe({
  next: (response) => console.log(response),
  error: (error) => console.error("Login failed", error),
});

MSM2.App.AuthHelper.logout$("/api/v1/logout", "role=user")
  .subscribe(() => { window.location.href = "/user/login.html"; });
```

## REST request and file upload

```js theme={null}
const response = await fetch("/api/v1/bean/request", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Site-Context": "my-site",
    "Lang-Context": "en",
  },
  body: JSON.stringify({
    beanId: "frameworkOperationServiceImpl",
    scope: "PROTOTYPE", functionName: "getLangCode", args: [],
  }),
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);

const formData = new FormData();
formData.append("file", file);
formData.append("payload", JSON.stringify({ destination: `${sellerId}/images` }));
formData.append("command", "UPLOAD_IMAGE");
await fetch("/api/v1/uploadImage", { method: "POST", body: formData });
```

## Form payload helper

```js theme={null}
import { getPayloadOfForm } from "msm-components/dist/services.js";

const payload = getPayloadOfForm(document.querySelector("form[data-profile]"));
console.log(payload);
```

## Cookie and language-aware URL helpers

```js theme={null}
import {
  setCookie, getCookie, languageAwareUrl,
} from "msm-components/dist/services.js";

setCookie("promo", "spring", null, null, "/");
console.log(getCookie("i18next"));
console.log(await languageAwareUrl("/catalog"));
```

## Custom topic subscription

```js theme={null}
const subscription = app.registerJsonWebSocket("orders", (event) => {
  console.log("Order event", event);
});
subscription.unsubscribe();
```

## Partial HTML render

```js theme={null}
app.renderElement(
  [{ elementId: "profile", path: "/components/profile", payload: {} }],
  { userId }
);
```

## Retry a failed service call

```js theme={null}
async function callWithRetry(task, attempts = 3) {
  let lastError;
  for (let attempt = 1; attempt <= attempts; attempt += 1) {
    try { return await task(); }
    catch (error) {
      lastError = error;
      await new Promise((resolve) => setTimeout(resolve, attempt * 500));
    }
  }
  throw lastError;
}

const response = await callWithRetry(() => callService(
  "frameworkOperationServiceImpl", "PROTOTYPE", "getLangCode", []
));
```

## JSON response handling

```js theme={null}
const response = await callService(
  "frameworkOperationServiceImpl", "PROTOTYPE", "getLangCode", []
);

if (response.result == null) {
  throw new Error("The service returned an empty result");
}
```
