Skip to content

Commit ad487ba

Browse files
paulrosenWebCoder49
authored andcommitted
Add Nuxt demo
1 parent 31d4886 commit ad487ba

File tree

2 files changed

+213
-6
lines changed

2 files changed

+213
-6
lines changed

docs/nuxt-demo-screenshot.png

23.4 KB
Loading

docs/vue-tutorial.md

Lines changed: 213 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
# Vue/Nuxt Tutorial
2-
1+
# Vue/Nuxt Tutorial - For Highlight.js Integration
2+
33
Vue and Nuxt have some similarities, but there is one big difference in how they can use this library. In Nuxt there is server side rendering (SSR) that will attempt to create the final HTML before sending the page to the browser. This cannot use any browser-specific things so the `code-input` component must be excluded from rendering until hydration in the browser.
44

5+
> [!NOTE]
6+
> The following demo is for integrating with `highlight.js` but if you follow the instructions in [the main README](../README.md) you can substitute highlight.js for Prism.js or a custom template.
7+
58
## Vue
69

710
### 1. Create a Vue app
@@ -56,11 +59,11 @@ npm install
5659
npm run dev
5760
```
5861

59-
You should be able to open your browser to the path that it prints out and see a started Vue app. If so, congratulations! Hit Ctrl-C to stop it.
62+
You should be able to open your browser to the path that it prints out and see a working Vue app. If so, congratulations! Hit Ctrl-C to stop it.
6063

6164
### 2. Add dependencies
6265

63-
This tutorial will use `highlight.js` for the syntax highlighting. If you are using a different method then adjust as needed.
66+
> This tutorial will use `highlight.js` for the syntax highlighting. If you are using a different method then adjust as needed.
6467
6568
Type this:
6669
```bash
@@ -79,6 +82,8 @@ vue({
7982
})
8083
```
8184

85+
So that Vue knows that `code-input` is not a Vue component.
86+
8287
### 3. Initialize the textarea
8388

8489
Create a component with whatever name you want. Perhaps `RichEditor.vue`. Paste the following into it:
@@ -131,7 +136,7 @@ In the generated file `HelloWorld.vue`, place the following line after the "gree
131136
<RichEditor />
132137
```
133138

134-
And put its input in the `<script>` section:
139+
And put its import in the `<script>` section:
135140
```vue
136141
import RichEditor from "@/components/RichEditor.vue";
137142
```
@@ -147,4 +152,206 @@ If all went well, you should see the following in the browser:
147152

148153
## Nuxt
149154

150-
TODO
155+
### 1. Create a Nuxt app
156+
157+
First, create a Nuxt project. (If you already have a Vue project then you can skip this step). On a command line, type this:
158+
```bash
159+
npm create nuxt@latest syntax-highlighter
160+
```
161+
At the time this tutorial was created, the output was the following:
162+
```
163+
Need to install the following packages:
164+
165+
Ok to proceed? (y) y
166+
167+
168+
> npx
169+
> "create-nuxt" syntax-highlighter
170+
171+
172+
.d$b.
173+
i$$A$$L .d$b
174+
.$$F` `$$L.$$A$$.
175+
j$$' `4$$:` `$$.
176+
j$$' .4$: `$$.
177+
j$$` .$$: `4$L
178+
:$$:____.d$$: _____.:$$:
179+
`4$$$$$$$$P` .i$$$$$$$$P`
180+
181+
ℹ Welcome to Nuxt!
182+
ℹ Creating a new project in syntax-highlighter.
183+
184+
✔ Which package manager would you like to use?
185+
npm
186+
◐ Installing dependencies...
187+
188+
> postinstall
189+
> nuxt prepare
190+
191+
✔ Types generated in .nuxt
192+
193+
added 882 packages, and audited 884 packages in 5m
194+
195+
185 packages are looking for funding
196+
run `npm fund` for details
197+
198+
found 0 vulnerabilities
199+
✔ Installation completed.
200+
201+
✔ Initialize git repository?
202+
No
203+
204+
✔ Would you like to install any of the official modules?
205+
Yes
206+
207+
✔ Pick the modules to install:
208+
none
209+
210+
✨ Nuxt project has been created with the v4 template. Next steps:
211+
› cd syntax-highlighter
212+
› Start development server with npm run dev
213+
214+
```
215+
216+
And just like the above instructions mention, do the following:
217+
```bash
218+
cd syntax-highlighter
219+
npm run dev
220+
```
221+
222+
You should be able to open your browser to the path that it prints out and see a working Vue app. If so, congratulations! Hit Ctrl-C to stop it.
223+
224+
### 2. Add dependencies
225+
226+
> This tutorial will use `highlight.js` for the syntax highlighting. If you are using a different method then adjust as needed.
227+
228+
Type this:
229+
```bash
230+
npm install @webcoder49/code-input
231+
npm install highlight.js
232+
```
233+
234+
In the file `vite.config.ts`, after the line `compatibilityDate`, add this so that Vue knows that `code-input` is not a Vue component:
235+
236+
```javascript
237+
vue: {
238+
compilerOptions: {
239+
isCustomElement: (tag) => tag === "code-input",
240+
},
241+
},
242+
```
243+
244+
Also add this:
245+
```javascript
246+
css: ['@webcoder49/code-input/code-input.css', 'highlight.js/styles/default.min.css'],
247+
```
248+
249+
So that the necessary css is loaded for code-input, and an example theme is loaded. You might want to replace the second file with your own theme, but you need the first file.
250+
251+
### 3. Initialize the textarea
252+
253+
Create a component with whatever name you want. Perhaps `app/components/RichEditor.vue`. Paste the following into it:
254+
255+
```vue
256+
<template>
257+
<div class="rich-editor">
258+
<!-- Use ClientOnly so that no SSR is done on the code-input component -->
259+
<ClientOnly>
260+
<code-input
261+
ref="elem"
262+
:name="name"
263+
:value="value"
264+
spellcheck="false"
265+
@input="emit('input', $event.target.value)"
266+
@code-input_load="loaded"
267+
></code-input>
268+
</ClientOnly>
269+
</div>
270+
</template>
271+
272+
<script lang="ts" setup>
273+
// For loading a highlighting engine - this example uses highlight.js
274+
import hljs from 'highlight.js/lib/core';
275+
import javascript from 'highlight.js/lib/languages/javascript';
276+
277+
// The following are optional.
278+
const emit = defineEmits<{
279+
// If you want a listener when the user changes the contents.
280+
(e: "input", value: string): void;
281+
// If you want to do more initialization after code-input is ready.
282+
(e: "ready", textarea: HTMLElement): void;
283+
}>();
284+
285+
const props = defineProps<{
286+
value: string; // The starting value for the textarea
287+
name: string; // The name that is used when the textarea is in a form
288+
}>();
289+
290+
// This contains the HTMLElement of the code-input component
291+
const elem = ref()
292+
293+
// Before it appears on the page, code-input needs to be initialized
294+
onBeforeMount(async () => {
295+
// Only if we're in the client
296+
if (import.meta.browser) {
297+
// Dynamically import code-input so that it is only in the browser
298+
const codeInput = await import("@webcoder49/code-input");
299+
const Template = (await import("@webcoder49/code-input/templates/hljs.mjs")).default;
300+
// Set up highlight.js
301+
hljs.registerLanguage('javascript', javascript);
302+
// Register that engine with code-input
303+
codeInput.registerTemplate("syntax-highlighted", new Template(hljs, []));
304+
}
305+
})
306+
307+
function loaded() {
308+
// This is called after the code-input is initialized and it has created a textarea.
309+
// If you have some further initialization for the textarea, then do it in this event.
310+
const ta = elem.value.querySelector('textarea')
311+
emit("ready", ta)
312+
}
313+
</script>
314+
315+
<style scoped>
316+
.rich-editor {
317+
border: 1px solid #bbbbbb;
318+
}
319+
code-input {
320+
resize: both; /* if you want the resizing control that textarea has */
321+
margin: 0; /* you can override other styles */
322+
font-family: "Fira Mono", Monaco, monospace;
323+
}
324+
</style>
325+
326+
<style>
327+
/* Notice that these styles aren't scoped */
328+
.hljs {
329+
background: #f1f1f1; /* here's how to change the background color. */
330+
}
331+
/* If you want to change the selection color */
332+
code-input textarea::selection {
333+
background: #6781ef;
334+
color: #ffffff;
335+
}
336+
</style>
337+
```
338+
### 4. Using the component
339+
340+
In the generated file `app.vue`, place the following line after the "NuxtRouteAnnouncer" line:
341+
```vue
342+
<RichEditor value="function hello() { console.log('world'); }" name="myEditor" />
343+
```
344+
345+
And put its import in the `<script>` section:
346+
```vue
347+
import RichEditor from "./components/RichEditor.vue";
348+
```
349+
350+
Restart the server:
351+
```bash
352+
npm run dev
353+
```
354+
355+
If all went well, you should see the following in the browser:
356+
357+
![nuxt-demo-screenshot.png](nuxt-demo-screenshot.png)

0 commit comments

Comments
 (0)