Comments (9)
@thomasbritton I've created a React component to render RichTexts, I think it might be optimized but it works for the moment
import React, { ReactNode } from 'react'
import classnames from 'classnames'
import css from './RichText.module.scss'
interface RichTextASTNode {
type: string
children: RichTextASTNode[]
level?: number
value?: string
bold?: boolean
italic?: boolean
url?: string
title?: string
target?: string
listType?: string
}
interface RichTextProps {
className?: string
data: RichTextASTNode
}
export function RichText({ className, data }: RichTextProps) {
return (
<div className={classnames(css.RichText, className)}>
{serializeRichTextASTNode(data)}
</div>
)
}
/**
* @workaround `@shopify/hydrogen-react` package does not export a RichText serializer function.
* @see https://github.com/Shopify/hydrogen-react/issues/150
* @todo Remove this workaround once the issue is resolved.
*
* @todo Should support internal links (there's no Shopify option in RichText for this right now)
*/
function serializeRichTextASTNode(
node: RichTextASTNode,
index: number = 0,
): ReactNode {
switch (node.type) {
case 'root':
return (
<div key={index}>{node.children.map(serializeRichTextASTNode)}</div>
)
case 'heading':
return React.createElement(
`h${node.level}`,
null,
node.children.map(serializeRichTextASTNode),
)
case 'paragraph':
return <p key={index}>{node.children.map(serializeRichTextASTNode)}</p>
case 'text':
return (
<span
key={index}
style={{
fontWeight: node.bold ? 'bold' : undefined,
fontStyle: node.italic ? 'italic' : undefined,
}}>
{node.value}
</span>
)
case 'link':
return (
<a key={index} href={node.url} title={node.title} target={node.target}>
{node.children.map(serializeRichTextASTNode)}
</a>
)
case 'list':
const List = node.listType === 'unordered' ? 'ul' : 'ol'
return (
<List key={index}>
{node.children.map((item) => (
<li key={item.children[0].value}>
{item.children.map(serializeRichTextASTNode)}
</li>
))}
</List>
)
default:
return null
}
}
export function toString(node: RichTextASTNode, result: string[] = []): string {
switch (node.type) {
case 'root':
node.children.forEach((child) => toString(child, result))
break
case 'heading':
case 'paragraph':
node.children.forEach((child) => toString(child, result))
result.push(' ')
break
case 'text':
result.push(node.value || '')
break
case 'link':
node.children.forEach((child) => toString(child, result))
break
case 'list':
node.children.forEach((item) => {
item.children.forEach((child) => toString(child, result))
result.push(' ')
})
break
}
return result.join('').trim()
}
from hydrogen.
Exciting to see rich text support getting worked on! Just wanted to call out that we've had really great experiences with the Contentful rich text schema. Specifically, one of the most useful features is the ability to inject either inline or block entity references. That has enabled us to e.g. personalize marketing copy using a customer's name or render an interactive React component within the copy.
I have a lot of first-hand experience working with Contentful rich text, happy to provide more context if that helps!
from hydrogen.
Any update on this?
Is there any other work-arounds that are possible to get working with a rich-text metafield within Hydrogen?
from hydrogen.
Having discussions around AST and the GraphQL API.
- Sanity call as an action item with Kusum.
- Slack coordination as an action item.
from hydrogen.
hey @TirmanSidhu @joe-szczepaniak - Can you please provide more context on this? Are there any specific requirements you need from the Hydrogen Metafield
component?
from hydrogen.
Hi @elisenyang, we are just sorting out the AST structure we plan to use for storing the metafield value, but also considering return serialized HTML to consumers for the initial release, since this might get us more adoption from developers. I'll reach out as soon as we are settled on something!
from hydrogen.
With Tirman moving on the status of this is unknown. If anyone has any updates, please advise!
from hydrogen.
@bastienrobert, impressive work! If you're interested, would love if you started a PR that we could collaborate on?
There are few things that would be great to add in the future, but this would be a great start on a v1. Only real comments are allowing an as
prop for the parent node (still default to div
), and then not assuming a CSS strategy, and not depend on classnames
.
from hydrogen.
One thing we'd love to provide is an ergonomic like …
<RichText
data={data}
components={
h1: (content) => <h1>...</h1>
h2: (content) => ...
....
}
/>
To provide more control over the rendering.
from hydrogen.
Related Issues (20)
- Subrequest Profiler 500 error (flameChartJs is not defined) HOT 3
- Better custom cart fragment typing HOT 1
- Linked to hydrogen storefront, now products aren't showing HOT 4
- Prevent <Image> from generating srcset which doesn't support image size HOT 2
- "npx shopify hydrogen debug cpu" is not working HOT 3
- Calling "npx shopify hydrogen deploy" in pipeline always shows the "Log in to Shopify" popup in Azure Pipelines HOT 1
- Shopify Auth cookies are not being cleared customerAccount.logout();
- Vite and MiniOxygen errors when using `vanilla-extract` and `formik`
- Vite Shopify Hydrogen Deploy Hardcodes the Removal of Client Source Maps HOT 1
- `page_viewed` Analytics events not firing when expected HOT 2
- Query injection possible in `urlRedirects` handler
- CUSTOMER ACCOUNT API Integration authorize always leads to 401 HOT 10
- QraphQL response from useLoaderData is always undefined on first render HOT 2
- CA API token not valid for cart buyerIdentity update HOT 1
- Build fails when overriding Vite `build.rollupOptions.output.entryFileNames` with templated string HOT 1
- Build fails when customizing SSR entrypoint due to hardcoded deletion of SSR build `assets/` (chunks) directory HOT 1
- Unexpected Server Error: atob() called with invalid base64-encoded data. in authorize->getNonce->decodeJwt HOT 6
- CSP nonce grows when using const passed from another file
- Infinite scrolling breaks on page refresh HOT 2
- `Money` component and `useMoney` hook don’t respect app language format
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from hydrogen.