Blocks
Image and Text
The Image and Text block is a common layout seen on websites and includes a title
, text
, button
and image
. There are also settings to allow the editor to decide which side they wish the image to appear on, to allow for alternating layouts on the page.
You can also extend this setting by adding additional positions for the image such as below the text, which you we will also show you examples for.
Front End
Image on the right
Image on the left
Image at the bottom
Content Model
The content model for the Image and Text block is as follows:
Text - Field Group
title
: Text Field - Required
text
: Long Text Field - Required
buttons
: Block - Optional
Image - Field Group
image
: Assets Field - Required
image_side
: Dropdown Field - Required
Code
The Image and Text block uses the BlockData
type from the Contento JavaScript SDK, the Image component from Next.js and the Button block.
There are two code versions of this block available.
Standard Layout
Allows editor to choose if they wish the image to be on the left or the right.
export default function ImageAndText({ block }: { block: BlockData }) {
const image = block.fields.image.assets.length > 0 ? (
<div>
<Image
src={block.fields.image.assets[0].asset.url}
alt={block.fields.image.assets[0].asset.description}
className="h-full w-full object-cover"
width={176}
height={176}
/>
</div>
) : null
return (
<div className="py-9 md:py-16">
<div className="grid items-center space-y-6 md:grid-cols-2 md:space-x-12">
{block.fields.image_side.selected_option.value === 'left' && (
<>{image}</>
)}
<div className="prose">
<h2 className="text-3xl font-semibold">{block.fields.title.text}</h2>
<div
dangerouslySetInnerHTML={{ __html: block.fields.text.text }}
className="text-lg"
/>
{block.fields.button.blocks.length > 0 &&
block.fields.button.blocks.map((button: BlockData) => {
return (
<Button key={button.fields.button_text.text} button={button} />
)
})}
</div>
{block.fields.image_side.selected_option.value === 'right' && (
<>{image}</>
)}
</div>
</div>
)
}
Add Bottom Layout
Allows editor to choose if they wish the image to be on the left, the right or at the bottom of the text.
import { BlockData } from '@gocontento/client'
import Image from 'next/image'
import Button from './Button'
export default function ImageAndText({ block }: { block: BlockData }) {
if (
block.fields.image_side.selected_option.value === 'left' ||
block.fields.image_side.selected_option.value === 'right'
) {
return <HorizontalImageAndText block={block} />
}
if (block.fields.image_side.selected_option.value === 'bottom') {
return <VerticalImageAndText block={block} />
}
}
function HorizontalImageAndText({ block }: { block: BlockData }) {
const image =
block.fields.image.assets.length > 0 ? (
<div>
<Image
src={block.fields.image.assets[0].asset.url}
alt={block.fields.image.assets[0].asset.description}
className="h-full w-full object-cover"
width={176}
height={176}
/>
</div>
) : null
return (
<div className="py-9 md:py-16">
<div className="grid items-center gap-y-6 md:grid-cols-2 md:space-x-12">
{block.fields.image_side.selected_option.value === 'left' && (
<>{image}</>
)}
<div className="prose order-first md:order-none">
<h2 className="text-3xl font-semibold leading-snug">
{block.fields.title.text}
</h2>
<div
dangerouslySetInnerHTML={{ __html: block.fields.text.text }}
className="text-lg"
/>
<div className="flex items-center gap-x-5">
{block.fields.buttons.blocks.length > 0 &&
block.fields.buttons.blocks.map((button: BlockData) => {
return (
<Button
key={button.fields.button_text.text}
button={button}
/>
)
})}
</div>
</div>
{block.fields.image_side.selected_option.value === 'right' && (
<>{image}</>
)}
</div>
</div>
)
}
function VerticalImageAndText({ block }: { block: BlockData }) {
return (
<div className="py-9 md:py-16">
<div className="flex flex-col items-center justify-center gap-y-6 md:space-y-12">
<div className="prose">
<h2 className="text-3xl font-semibold leading-snug md:text-center md:text-5xl">
{block.fields.title.text}
</h2>
<div
dangerouslySetInnerHTML={{ __html: block.fields.text.text }}
className="text-lg md:text-center"
/>
<div className="flex items-center gap-x-5 md:justify-center">
{block.fields.buttons.blocks.length > 0 &&
block.fields.buttons.blocks.map((button: BlockData) => {
return (
<Button
key={button.fields.button_text.text}
button={button}
/>
)
})}
</div>
</div>
{block.fields.image.assets.length > 0 && (
<div>
<Image
src={block.fields.image.assets[0].asset.url}
alt={block.fields.image.assets[0].asset.description}
className="h-full w-full object-cover"
width={750}
height={600}
/>
</div>
)}
</div>
</div>
)
}