Skip to content

Commit

Permalink
docs: added Astro w/ React/Preact Components Integration
Browse files Browse the repository at this point in the history
  • Loading branch information
LoneExile authored and umputun committed Jun 29, 2023
1 parent 33a6d6d commit 64188e5
Showing 1 changed file with 124 additions and 12 deletions.
136 changes: 124 additions & 12 deletions site/src/docs/manuals/integration-with-astro/index.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Using Remark42 in Astro (w/Svelte Components)
# Using Remark42 in Astro

[Astro](https://astro.build/) is an all-in-one web framework for building fast, content-focused websites.

Expand All @@ -8,12 +8,12 @@
- **Easy to use:** You don't need to be an expert to build something with Astro.
- **Fully-featured, but flexible:** Over 100+ Astro integrations to choose from.

While Astro supports numerous front-end framework [integrations](https://docs.astro.build/en/guides/integrations-guide/#official-integrations) (e.g. React, Vue, SolidJS, etc.) this integration implements [Svelte](https://docs.astro.build/en/guides/integrations-guide/svelte/) components and Astro's [islands architecture](https://docs.astro.build/en/concepts/islands/) for partial hydration.
While Astro supports numerous front-end framework [integrations](https://docs.astro.build/en/guides/integrations-guide/#official-integrations) (e.g. React, Vue, SolidJS, etc.)



## Svelte Component (Embedded Frame)
### remark42-embed.svelte
## w/ Svelte Components
### Svelte Component (Embedded Frame)
#### remark42-embed.svelte
```js
<svelte:head>
<script async lang="javascript">
Expand Down Expand Up @@ -41,8 +41,8 @@ While Astro supports numerous front-end framework [integrations](https://docs.as
<div id="remark42" />
```
## Astro Layout (Page)
### blogpageLayout.astro (partial Astro layout)
### Astro Layout (Page)
#### blogpageLayout.astro (partial Astro layout)
```js
---
...
Expand All @@ -65,8 +65,8 @@ const { frontmatter } = Astro.props;
```
Note the use of the `client:visible` directive which will hydrate the component once the element becomes visible.
## Svelte Component (Counter)
### remark42-counter.svelte
### Svelte Component (Counter)
#### remark42-counter.svelte
```js
<script>
export let url;
Expand Down Expand Up @@ -98,8 +98,8 @@ Note the use of the `client:visible` directive which will hydrate the component
<span class="remark42__counter" data-url={url.href} />
```
## Astro Component (Card)
### blogCard.astro (partial Astro component)
### Astro Component (Card)
#### blogCard.astro (partial Astro component)
```js
---
const { post } = Astro.props;
Expand All @@ -121,4 +121,116 @@ import Remark42Count from "../components/remark42-count.svelte";
...
</div>
```
Note the use of the `client:idle` directive which will hydrate the component once the page has completed the initial load.
Note the use of the `client:idle` directive which will hydrate the component once the page has completed the initial load.
## w/ React/Preact Components
This example demonstrates how to integrate the Remark42 commenting system using a React/Preact component. The component manages the insertion and removal of the Remark42 script in the DOM, provides the ability to toggle between light and dark themes, and includes areas for embedding comments and displaying a comment count. This makes it easy to incorporate a commenting system into a React/Preact application.
#### Comment.tsx
```ts
import {useEffect, useState} from 'preact/hooks'

declare global {
// Declare the global types for REMARK42 and remark_config so they can be used in this module.
interface Window {
REMARK42: any
remark_config: any
}
}

// Function to insert the Remark42 script into the DOM.
const insertScript = (id: string, parentElement: HTMLElement) => {
const script = window.document.createElement('script')
script.type = 'text/javascript'
script.async = true
script.id = id

// Get the current URL, and remove trailing slash if it exists.
let url = window.location.origin + window.location.pathname
if (url.endsWith('/')) {
url = url.slice(0, -1)
}

// Get the host from the environment variables.
const host = import.meta.env.PUBLIC_REMARK_URL

// Set the inner HTML of the script to load Remark42.
script.innerHTML = `
var remark_config = {
host: "${host}",
site_id: "remark",
url: "${url}",
theme: "dark",
components: ["counter", "embed"],
};
!function(e,n){for(var o=0;o<e.length;o++){var r=n.createElement("script"),c=".js",d=n.head||n.body;"noModule"in r?(r.type="module",c=".mjs"):r.async=!0,r.defer=!0,r.src=remark_config.host+"/web/"+e[o]+c,d.appendChild(r)}}(remark_config.components||["embed"],document);`
// Append the script to the parent element.
parentElement.appendChild(script)
}
// Function to remove the Remark42 script from the DOM.
const removeScript = (id: string, parentElement: HTMLElement) => {
const script = window.document.getElementById(id)
if (script) {
parentElement.removeChild(script)
}
}
// Function to manage the insertion and removal of the Remark42 script.
const manageScript = () => {
if (!window) {
return () => {}
}
const {document} = window
if (document.getElementById('remark42')) {
insertScript('comments-script', document.body)
}
// Return a cleanup function to remove the script when the component unmounts.
return () => removeScript('comments-script', document.body)
}
export function Comments() {
// State for tracking the current theme.
const [theme, setTheme] = useState('dark')
// Use effect to manage the Remark42 script.
useEffect(manageScript, [])
// Use effect to update the theme when it changes.
useEffect(() => {
if (window.REMARK42) {
window.REMARK42.changeTheme(theme)
}
}, [theme])
// Function to toggle the theme.
const toggleTheme = () => {
setTheme((prevTheme) => (prevTheme === 'dark' ? 'light' : 'dark'))
}
return (
<>
<h2>Comments</h2>
{/* Button to change the theme. */}
<button onClick={toggleTheme}>Change Theme</button>
{/* The span where Remark42 will embed the comment count. */}
<p>
There are <span className="remark42__counter"></span> comments.
</p>
{/* The div where Remark42 will embed the comments. */}
<div id="remark42"></div>
</>
)
}
```
#### Here how to use it in your Astro component.
```js
---
import { Comments } from "@components/Comment";
---
<Comments client:visible />
```

0 comments on commit 64188e5

Please sign in to comment.