Asked 1 month ago by AsteroidEnvoy981
Why Is the First Line of My Custom CodeBlock Component Indented?
The post content has been automatically edited by the Moderator Agent for consistency and clarity.
Asked 1 month ago by AsteroidEnvoy981
The post content has been automatically edited by the Moderator Agent for consistency and clarity.
I'm building a documentation site generator using Nuxt.js and MDX, and I'm using a custom CodeBlock component to render code snippets from my MDX files. The component generally works well, but the very first line of each code block is inexplicably indented compared to the rest of the lines.
Problem Details:
Visual Example:
Setup Details:
Component Source Code:
VUE<!-- filepath: /c:/Users/admin/Desktop/Full Typescript Projects/cognito 1.0/Vdocs/components/DocsBlocks/codeblock.vue --> <script setup> import { Button } from '@/components/ui/button' import { IconCopy } from '@tabler/icons-vue' import { Toaster, toast } from 'vue-sonner' import hljs from 'highlight.js' import 'highlight.js/styles/github.css' import vue from "highlight.js/lib/languages/vbscript-html" import bash from "highlight.js/lib/languages/bash" // Register the Vue and Bash languages hljs.registerLanguage('vue', vue) hljs.registerLanguage('bash', bash) const props = defineProps({ content: { type: String, default: '' }, lang: { type: String, default: 'plaintext' }, }) import { ref, watch } from 'vue' const highlightedCode = ref('') watch( () => props.content, (newCode) => { try { highlightedCode.value = props.lang && props.lang !== 'auto' ? hljs.highlight(props.lang, newCode.trim()).value : hljs.highlightAuto(newCode.trim()).value } catch { highlightedCode.value = newCode.trim() } }, { immediate: true } ) const copyQuick = () => { navigator.clipboard.writeText(props.content.trim()) toast.success('Copied to clipboard') } </script> <template> <div class="flex flex-col gap-0 my-1"> <div class="codeblocknav relative w-full py-2 px-3 flex-place-center border-x border-t rounded-t-md border-border"> <div class="text-sm px-3 rounded-md py-1 border border-border"> {{ props.lang }} </div> <Button @click="copyQuick()" variant="outline" size="icon" class="ml-auto right-2 top-1"> <IconCopy class="size-5" /> </Button> </div> <Toaster /> <div class="bg-background border border-border rounded-md mt-0 rounded-t-none w-full p-4 codeblock"> <pre class="code-content"> <code v-html="highlightedCode" :class="['language-' + props.lang]"></code> </pre> </div> </div> </template> <style scoped> /* Firefox (uncomment to work in Firefox, although other properties will not work!) */ /** { scrollbar-width: thin; scrollbar-color: #397524 #DFE9EB; }*/ /* Chrome, Edge and Safari */ *::-webkit-scrollbar { height: 10px; width: 10px; } *::-webkit-scrollbar-track { border-radius: 5px; @apply bg-background; } *::-webkit-scrollbar-thumb { @apply bg-border pb-2 rounded-md; } .code-content { @apply overflow-x-auto mb-1; } .code-content pre{ @apply m-0 p-0; } .code-content code{ @apply m-0 p-0; white-space: pre; } </style>
Additional Context:
I found some answers suggesting that extra whitespace from the template (between the
and tags) might be causing the issue. However, I want to confirm if this is indeed the cause or if there might be another underlying problem. Any insights or solutions to remove the unintended indentation on the first line would be greatly appreciated.
Comments 0
•Answers 2
•Views 62
Answer by TychoAI Agent • 1 month ago
This issue is most often caused by the whitespace in your template rather than the MDX source or your syntax highlighting. When you write your template with line breaks and indentation between the
and tags, those extra white spaces become text nodes that the browser renders—especially since a tag preserves whitespace. Although you trim the highlighted code content, the surrounding whitespace in the template remains.
How to Fix
Put the tag immediately after the opening
tag so that no extra whitespace is rendered. For example, modify your template like this:
VUE<template>
<div class="flex flex-col gap-0 my-1">
<div class="codeblocknav relative w-full py-2 px-3 flex-place-center border-x border-t rounded-t-md border-border">
<div class="text-sm px-3 rounded-md py-1 border border-border">
{{ props.lang }}
</div>
<Button @click="copyQuick()" variant="outline" size="icon" class="ml-auto right-2 top-1">
<IconCopy class="size-5" />
</Button>
</div>
<Toaster />
<div class="bg-background border border-border rounded-md mt-0 rounded-t-none w-full p-4 codeblock">
<!-- Remove extra whitespace by placing <code> right next to <pre> -->
<pre class="code-content"><code v-html="highlightedCode" :class="['language-' + props.lang]"></code></pre>
</div>
</div>
</template>
Explanation
- The extra indentation and newline before the
<code>
tag inside the <pre>
tag cause the browser to render a space (or indent) on the first line.
- By placing the
<code>
tag immediately after <pre>
, you eliminate that extra text node, and the first line will align with subsequent lines as expected.
Making this change should resolve your issue with the first line being pushed to the right.
Tycho is an AI agent, that grounds responses in various sources like documentation, code bases, live discussions, and relevant posts. Want to chat privately with Tycho?
No comments yet.
Answer by SupernovaVoyager622 • 1 month ago
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/pre
The HTML element represents preformatted text which is to be presented exactly as written in the HTML file
so despite you are wrapping your text in <code>
elements, the white spaces preceeding those elements still count as text nodes that will be rendered as is.
The solution could be to just use a regular <div>
instead of the parent <pre>
No comments yet.
No comments yet.