Best way to get a react component's raw code?

Is it possible to get a component's raw code? For example.
function Post() {
return (
<div>post1</div>
)
}
function Post() {
return (
<div>post1</div>
)
}
then something like this
<code>{getRawCode(Post)}</code>
<code>{getRawCode(Post)}</code>
Basically, I want something like this: https://ui.shadcn.com/docs/components/accordion, where I can see the preview of the component and the raw code. Technically, I can just copy/paste the component's code into the <code> element but I want to have a single source of truth. And I did try looking at shadcn/ui repo but I did not understand how it worked at all.
9 Replies
iDarkLightning
iDarkLightning11mo ago
Not really unless you read the file
Luc Ledo
Luc LedoOP11mo ago
I tried that too. It doesn't give the raw code. Unless I'm doing something wrong.
iDarkLightning
iDarkLightning11mo ago
You have to read the .ts file not the build output
Luc Ledo
Luc LedoOP11mo ago
yes, I read the .tsx file
iDarkLightning
iDarkLightning11mo ago
then what exactly are you getting if not the contents of the file im going to be honest w/ you, don't do this
Alky
Alky11mo ago
The way shadcn does it's not really on his repo. The only thing you can learn is here and here. He uses a lot of plugins and something called "contentlayer", which is under all gitignores. And based on those files, he really parses it in a way that the "<ComponentPreview />" receives just a name prop, and the search for the doc e in which contains the "doc.body.code" property, which is generated in build time, i assume. If you wanna do something similar, maybe wrap your components inside some specific comment "tags", then create a script that read the some folders file and grab(if exists) just the content inside the specified tags and then make it available for your project in some kind o way, like an object indexed by name. Anyway, i don't think is gonna be any fast work
GitHub
ui/apps/www/content/docs/components at main · shadcn-ui/ui
Beautifully designed components that you can copy and paste into your apps. Accessible. Customizable. Open Source. - shadcn-ui/ui
Luc Ledo
Luc LedoOP11mo ago
I do know about contentlayer. What I don't understand is how he can use ComponentPreview without passing in any children even though it's required.
<ComponentPreview
name="accordion-demo"
className="[&_.preview>[data-orientation=vertical]]:sm:max-w-[70%]"
/>
<ComponentPreview
name="accordion-demo"
className="[&_.preview>[data-orientation=vertical]]:sm:max-w-[70%]"
/>
He uses this to get the raw code...
const [config] = useConfig()
const index = styles.findIndex((style) => style.name === config.style)

const Codes = React.Children.toArray(children) as React.ReactElement[]
const Code = Codes[index]
const [config] = useConfig()
const index = styles.findIndex((style) => style.name === config.style)

const Codes = React.Children.toArray(children) as React.ReactElement[]
const Code = Codes[index]
But I tried a simplified example in my project and it didn't work because there is no children. So then I pass in some children but still I didn't get raw code back. There must be some easier way to do this since it's a common problem for any coding example, this is way too complicated. I got it working. Just had to specify utf8 encoding lol.
iDarkLightning
iDarkLightning11mo ago
yes but cursed
Luc Ledo
Luc LedoOP11mo ago
I don't see any better way to do this. Shadcn solution is much more cursed imo. Solution in case anyone ever needs this.
import fs from "fs"
import path from "path"

const mdxDir = path.join(process.cwd(), "app/mdx")

export function ComponentPreview({
slug,
Component,
}: {
slug: string
Component: () => JSX.Element
}) {
const filePath = path.join(mdxDir, `${slug}.tsx`)
const fileContent = fs.readFileSync(filePath, "utf8")
return (
<>
<Component />
<pre>
<code>{fileContent}</code>
</pre>
</>
)
}
import fs from "fs"
import path from "path"

const mdxDir = path.join(process.cwd(), "app/mdx")

export function ComponentPreview({
slug,
Component,
}: {
slug: string
Component: () => JSX.Element
}) {
const filePath = path.join(mdxDir, `${slug}.tsx`)
const fileContent = fs.readFileSync(filePath, "utf8")
return (
<>
<Component />
<pre>
<code>{fileContent}</code>
</pre>
</>
)
}
Want results from more Discord servers?
Add your server