Vue Integration
Vue is the frontend framework used to power MarkBind’s dynamic UI components and client-side interactivity. Vue components are rendered both on the server and browser depending on the context:
<panel>
with preload='false'
are dynamically loaded via CSR.For more details on how MarkBind uses Vue for server-side rendering and hydration (and the common caveats developers should be aware of, including hydration issues), refer to the Server Side Rendering page.
MarkBind uses a library of custom Vue components, which are a mix of Bootstrap-based components and those tailored for educational websites. These components are designed to meet the specific needs of MarkBind's use cases. For a list of some components and directives added for MarkBind's use, refer to the UI components library.
Vue components are particularly useful for implementing complex features and interactivity that go beyond what static HTML and Markdown can provide. For details implementing a MarkBind component as a Vue component, refer here.
Vue components in MarkBind are used for:
Encapsulating Complex Behavior: Vue components allow for reusable, self-contained logic and interactivity.
Dynamic Content Loading: Components like <panel>
with preload='false'
use Vue to dynamically load content after the page is rendered.
Interactive Features: Components like modals, quizzes, and tooltips rely on Vue for their interactive behavior.
Integration with External Libraries: Vue components can wrap external libraries (e.g., Vue Final Modal for modals) to provide a seamless user experience.
In addition to custom Vue components, MarkBind also makes use of custom Vue directives to provide enhanced interactivity and DOM manipulation behaviors. These directives encapsulate logic that operates directly on the DOM elements, complementing the declarative nature of Vue templates.
v-closeable
directive, used here to remove content, provides functionality to toggle the visibility of content sections. It dynamically wraps the directive’s target content in a container, adds a close button and show label, and sets up the necessary event handlers.MarkBind leverages Server-side Rendering (SSR) to pre-render Vue components into static HTML during the build process. This pre-rendered HTML is served to the client, reducing the time required for the page to become interactive. It also ensures that the content is visible immediately, even before JavaScript is executed, eliminating the Flash-of-Unstyled-Content (FOUC).
MarkBind uses Server-side Rendering (SSR) to pre-render page content into static HTML during the build process. Here is an overview of the workflow during the build process:
Server-side Compilation of Render Function: MarkBind takes the final HTML page content (product of Content Processing Flow) and compiles it into a render function using the compileTemplate
function from vue/compiler-sfc
. This render function is saved as a JavaScript file (e.g., <page-name>.page-vue-render.js
) in the same directory as the HTML file. This script file is served alongside the static HTML and injected into the final page template, for the purpose of hydration. It is also directly used in SSR to generate the static HTML.
Server-side Render of HTML: On the server, MarkBind initializes a separate Vue instance solely for SSR. It registers the custom Vue components and directives bundled by core-web onto this Vue instance. The Vue instance uses the render function previously compiled to generate static HTML via the renderToString
function from vue/server-renderer
.
Client-side Hydration: On the client side (e.g., a web browser), the HTML is served with the injected render function. The Vue app is initialized using createSSRApp
in index.js. Thereafter, the Vue instance takes over and hydrates the static HTML. For more details on hydration and potential hydration issues, refer to Client-side Hydration.
In specific cases, MarkBind uses Client-side Rendering (CSR) exclusively to dynamically load content. A key example is the <panel>
component. When the src
attribute is set to a remote page to be loaded as the content, the preload
attribute is false
by default. As the content is not preloaded and loaded dynamically after the page is rendered, it wil conduct CSR, where:
This section provides a deeper look into how MarkBind sets up and initializes the Vue application on the client side. It is intended for developers who are interested in understanding the underlying execution flow in more detail.
The core Vue app is initialized in core-web/src/index.js
, which serves as the entry point for the client-side Vue application. This file is part of the packages/core-web/
library — a client-side bundle generated by MarkBind. It contains initialization scripts, the bundled UI components library, and shared logic used across all rendered sites. This bundle is included in the final site HTML and executed in the web browser when a user visits a generated MarkBind site.
<script>
tag that loads the core-web
bundle.core-web/src/index.js
.index.js
) defines the setup()
function, which is exported and later called in the HTML template (page.njk
).setup()
, the Vue app is initialized using createSSRApp()
, where the render
function was previously attached as a global variable, generated during SSR and served in <page-name>.page-vue-render.js
. (injected via SSR in PageVueServerRenderer.ts
).<modal>
, <tooltip>
), Custom directives (e.g., v-tooltip
, v-closeable
and Global configuration (e.g., $vfm
for modals).#app
) using app.mount('#app')
.<style>
tags: Replaces placeholder <script>
tags with their original <style>
tags.siteData.json
.This architecture allows MarkBind to combine fast server-side initial rendering with interactive client-side behavior, ensuring a seamless and performant experience.