Skip to content

Remix Integration

Remix is a modern, full-stack framework with a strong emphasis on user experience and web standards.

These instructions assume you’ve already created a JamComments account as well as a “site” within that account. If you haven’t, learn more about that process on the Getting Started page.


In order to use this plugin, you’ll need a JamComments account, where you’ll also need to have created a site and generated an API key.


Terminal window
npm install @jam-comments/remix

Environment Variables

After installation, set the following environment variables for your Remix application:

Environment Variables

JAM_COMMENTS_DOMAINThe root domain of your site (without https://).
JAM_COMMENTS_API_KEYThe API key found in your account settings.
JAM_COMMENTS_ENVIRONMENTThe environment JamComments will use to determine if it should render dummy comments. If this isn’t set, NODE_ENV is used.


In order to fetch comments for a route, we’ll use the fetchMarkup() function from @jam-comments/remix/server. To avoid polluting browser code with Node built-ins, it’s recommended that you re-export that function from a *.server.ts file:

export { fetchMarkup } from "@jam-comments/remix/server";

Then, retrieve the data and pass it to the <JamComments /> component. For more information on fetch options, see here.

// posts.$slug.tsx
import getPostFromWherever from "./get-posts";
import { json } from "@remix-run/node";
import { JamComments } from "@jam-comments/remix";
import { fetchMarkup } from "@jam-comments/remix/server";
export const loader = async ({ params }) => {
const post = await getPostFromWherever(params.slug);
const postSchema = {
"@context": "",
"@type": "BlogPosting",
// ...the rest
const markup = await fetchMarkup({
domain: process.env.JAM_COMMENTS_DOMAIN,
apiKey: process.env.JAM_COMMENTS_API_KEY,
path: `/posts/${params.slug}`,
schema: postSchema, //<-- optional
tz: "America/Chicago", // <-- optional
return json({ post, markup });
export default function Post() {
const { post, markup } = useLoaderData();
return (
<div dangerouslySetInnerHTML={{ __html: content }}></div>
{/* Comments will be rendered here: */}
<JamComments markup={markup} />


The source for this plugin is open to contributions. If you have a bug fix or idea for improvement, leave a pull request or issue in the GitHub repository.