Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add Storyblok example #381

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions storyblok/.env-example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
STORYBLOK_PREVIEW_TOKEN="your-token"
4 changes: 4 additions & 0 deletions storyblok/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/** @type {import('eslint').Linter.Config} */
module.exports = {
extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"],
};
8 changes: 8 additions & 0 deletions storyblok/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
node_modules

/.cache
/build
/public/build
.env
localhost-key.pem
localhost.pem
12 changes: 12 additions & 0 deletions storyblok/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Storyblok example

This is an example showing a basic integration of Remix with [Storyblok](https://storyblok.com).

## Example

This example shows how to integrate Storyblok in a Remix application, so we can manage the content of our project inside a Headless CMS.we can enable a live preview of the content that's created, using Storyblok's Visual Editor.

## Related Links
- [Storyblok](https://storyblok.com)
- here is the [documentation](https://www.storyblok.com/tp/headless-cms-remix) to get started
- Remix tech hub in Storyblok [here](https://www.storyblok.com/tc/remix)
11 changes: 11 additions & 0 deletions storyblok/app/components/Feature.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { storyblokEditable } from "@storyblok/react";

const Feature = ({ blok }) => {
return (
<div {...storyblokEditable(blok)} key={blok._uid} className="w-full p-12 bg-[#f7f6fd] rounded-[5px] text-center">
<h3 className="text-2xl text-[#1d243d] font-bold"> {blok.name} </h3>
</div>
);
};

export default Feature;
13 changes: 13 additions & 0 deletions storyblok/app/components/Grid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { storyblokEditable, StoryblokComponent } from "@storyblok/react";

const Grid = ({ blok }) => (
<ul {...storyblokEditable(blok)} key={blok._uid} className="container mx-auto grid md:grid-cols-3 gap-12 my-12 place-items-center">
{blok.columns.map((blok) => (
<li key={blok._uid}>
<StoryblokComponent blok={blok} />
</li>
))}
</ul>
);

export default Grid;
11 changes: 11 additions & 0 deletions storyblok/app/components/Page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { storyblokEditable, StoryblokComponent } from "@storyblok/react";

const Page = ({ blok }) => (
<main {...storyblokEditable(blok)} key={blok._uid} className="px-4">
{blok.body.map((nestedBlok) => (
<StoryblokComponent blok={nestedBlok} key={nestedBlok._uid} />
))}
</main>
);

export default Page;
11 changes: 11 additions & 0 deletions storyblok/app/components/Teaser.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { storyblokEditable } from "@storyblok/react";

const Teaser = ({ blok }) => {
return (
<div {...storyblokEditable(blok)} key={blok._uid} className="py-32 text-6xl text-[#50b0ae] font-bold text-center">
{blok.headline}
</div>
);
};

export default Teaser;
69 changes: 69 additions & 0 deletions storyblok/app/root.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { json, type MetaFunction } from "@remix-run/node";
import {
Links,
LiveReload,
Meta,
Outlet,
Scripts,
ScrollRestoration,
useLoaderData,
} from "@remix-run/react";
import { storyblokInit, apiPlugin } from "@storyblok/react";
import Feature from "./components/Feature";
import Grid from "./components/Grid";
import Page from "./components/Page";
import Teaser from "./components/Teaser";


const isServer = typeof window === "undefined";

const accessToken = isServer
? process.env.STORYBLOK_PREVIEW_TOKEN
: //@ts-ignore
window.env.STORYBLOK_PREVIEW_TOKEN;

export async function loader() {
return json({env: process.env.STORYBLOK_PREVIEW_TOKEN})
}

const components = {
feature: Feature,
grid: Grid,
teaser: Teaser,
page: Page,
};

storyblokInit({
accessToken,
use: [apiPlugin],
components,
});

export const meta: MetaFunction = () => ({
charset: "utf-8",
title: "New Remix App",
viewport: "width=device-width,initial-scale=1",
});

export default function App() {
const {env} = useLoaderData<typeof loader>()
return (
<html lang="en">
<head>
<Meta />
<Links />
</head>
<body>
<Outlet />
<script
dangerouslySetInnerHTML={{
__html: `window.env = ${JSON.stringify(env)}`,
}}
/>
<ScrollRestoration />
<Scripts />
<LiveReload />
</body>
</html>
);
}
36 changes: 36 additions & 0 deletions storyblok/app/routes/$.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { json } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";

import {
getStoryblokApi,
useStoryblokState,
StoryblokComponent,
} from "@storyblok/react";

export default function Page() {
let story = useLoaderData();
story = useStoryblokState(story);

return (
<>
<StoryblokComponent blok={story.content} />
</>
)
};

export const loader = async ({ params, preview = false }) => {
let slug = params["*"] ?? "home";
let blogSlug = params["*"] === "blog/" ? "blog/home" : null;

let sbParams = {
version: "draft"
};

if (preview) {
sbParams.version = "draft"
sbParams.cv = Date.now()
};

let { data } = await getStoryblokApi().get(`cdn/stories/${blogSlug ? blogSlug : slug}`, sbParams);
return json(data?.story, preview);
};
1 change: 1 addition & 0 deletions storyblok/app/routes/_index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default, loader } from "./$";
30 changes: 30 additions & 0 deletions storyblok/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"private": true,
"sideEffects": false,
"scripts": {
"build": "remix build",
"dev": "remix dev",
"start": "remix-serve build",
"typecheck": "tsc"
},
"dependencies": {
"@remix-run/node": "^1.19.3",
"@remix-run/react": "^1.19.3",
"@remix-run/serve": "^1.19.3",
"@storyblok/react": "^2.4.7",
"isbot": "^3.6.5",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@remix-run/dev": "^1.19.3",
"@remix-run/eslint-config": "^1.19.3",
"@types/react": "^18.0.25",
"@types/react-dom": "^18.0.8",
"eslint": "^8.27.0",
"typescript": "^4.8.4"
},
"engines": {
"node": ">=14.0.0"
}
}
Binary file added storyblok/public/favicon.ico
Binary file not shown.
11 changes: 11 additions & 0 deletions storyblok/remix.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/** @type {import('@remix-run/dev').AppConfig} */
module.exports = {
future: {
v2_routeConvention: true,
},
ignoredRouteFiles: ["**/.*"],
// appDirectory: "app",
// assetsBuildDirectory: "public/build",
// publicPath: "/build/",
// serverBuildPath: "build/index.js",
};
2 changes: 2 additions & 0 deletions storyblok/remix.env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/// <reference types="@remix-run/dev" />
/// <reference types="@remix-run/node" />
7 changes: 7 additions & 0 deletions storyblok/sandbox.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"hardReloadOnChange": true,
"template": "remix",
"container": {
"port": 3000
}
}
22 changes: 22 additions & 0 deletions storyblok/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"],
"compilerOptions": {
"lib": ["DOM", "DOM.Iterable", "ES2019"],
"isolatedModules": true,
"esModuleInterop": true,
"jsx": "react-jsx",
"moduleResolution": "node",
"resolveJsonModule": true,
"target": "ES2019",
"strict": true,
"allowJs": true,
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
"paths": {
"~/*": ["./app/*"]
},

// Remix takes care of building everything in `remix build`.
"noEmit": true
}
}