# Usage

Learn how to serve personalized content without changing your application.

The integration is transparent. You fetch and render your Storyblok stories exactly as you do today, and both personalization and AB tests apply automatically to the blocks you [linked](/immersion/integrations/cms/storyblok/guide#connecting-blocks) to a [slot](/explanation/slot).

The integration also forwards the locale from your Storyblok request to Croct, so each visitor gets personalized content for the matching [locale](/explanation/slot#localization).

## Fetch and render a story \[#usage]

Fetch a story with the Storyblok SDK as usual and render it with your components. The integration intercepts the request and replaces any linked blocks with personalized content behind the scenes.

**JavaScript**

```js
const {data} = await storyblokApi.get('cdn/stories/home', {
  version: 'published',
  language: 'en',
});

// Render data.story.content.body with your own components.
```

**React**

```jsx
import {useStoryblok, StoryblokComponent} from '@storyblok/react';

export function Home() {
  const story = useStoryblok('home', {
    version: 'published',
    language: 'en',
  });

  return story !== null ? <StoryblokComponent blok={story.content} /> : null;
}
```

**Next**

```jsx
import {StoryblokServerStory} from '@storyblok/react/rsc';
import {getStoryblokApi} from '@/lib/storyblok';

export default async function Home() {
  const storyblokApi = getStoryblokApi();

  const {data} = await storyblokApi.get('cdn/stories/home', {
    version: 'published',
    language: 'en',
  });

  return <StoryblokServerStory story={data.story} />;
}
```

**Vue**

```vue
<script setup>
import {useStoryblok} from '@storyblok/vue';

const story = await useStoryblok('home', {
  version: 'published',
  language: 'en',
});
</script>

<template>
  <StoryblokComponent v-if="story" :blok="story.content" />
</template>
```

**Nuxt**

```vue
<script setup>
const story = await useAsyncStoryblok('home', {
  version: 'published',
  language: 'en',
});
</script>

<template>
  <StoryblokComponent v-if="story" :blok="story.content" />
</template>
```

**PHP**

```php
<?php
use Storyblok\Api\Request\StoryRequest;

$response = $stories->bySlug('home', new StoryRequest(language: 'en'));

// Render $response->story['content']['body'] in your template.
```

**Symfony**

```php
<?php
namespace App\Controller;

use Storyblok\Api\Request\StoryRequest;
use Storyblok\Api\StoriesApiInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;

final class HomeController extends AbstractController
{
    private StoriesApiInterface $stories;

    public function __construct(StoriesApiInterface $stories)
    {
        $this->stories = $stories;
    }

    public function index(): Response
    {
        $response = $this->stories->bySlug('home', new StoryRequest(language: 'en'));

        return $this->render('home.html.twig', [
            'story' => $response->story,
        ]);
    }
}
```

**Laravel**

```php
<?php
namespace App\Http\Controllers;

use Illuminate\Contracts\View\View;
use Storyblok\Api\Request\StoryRequest;
use Storyblok\Api\StoriesApiInterface;

class HomeController extends Controller
{
    private StoriesApiInterface $stories;

    public function __construct(StoriesApiInterface $stories)
    {
        $this->stories = $stories;
    }

    public function index(): View
    {
        $response = $this->stories->bySlug('home', new StoryRequest(language: 'en'));

        return view('home', [
            'story' => $response->story,
        ]);
    }
}
```

The `language` you pass is forwarded to Croct, so each visitor gets the personalized content for the matching [locale](/explanation/slot#localization).

## What to expect \[#verify]

When you load a page that renders a linked block:

- Visitors not matched by any experience see the original Storyblok content.
- Visitors matched by a [Personalized experience](/explanation/experience/introduction) or an [AB test](/explanation/experiment) see the personalized content in place of the block, with no extra code.

To watch it happen end to end, publish an experience targeting the connected slot and reload the page, as described in the [Storyblok integration tutorial](/immersion/integrations/cms/storyblok/integration#try-it-out).

## Explore

- [Storyblok integration](/immersion/integrations/cms/storyblok/integration): Learn how to integrate Croct with your Storyblok space.
- [API reference](api): Explore the functions and classes the integration provides.
