Welcome to the Textuality Setup Guide! Here, you can find everything you need to know about setting up Textuality. Setup should take no longer than 5 minutes.
#
Setup
#
Creating a Textuality Account
To get started with Textuality, you need to create an account. You can do this by visiting the Textuality website and clicking on the "Sign Up" button. You will be asked to provide your email address and create a password. Sign Up
#
Creating a Textuality Page
Creating a Textuality page is easy. You can do this by following these steps:
- In the page home, click on the "Create Page" button.
- Enter a title for your page.
- Enter a description for your page.
- On the dropdown menu, select the category for your page.
- Click on the "Create" button.
#
Setting Up Textuality on Your Website
Before you can see content on your website you will need to create content on Textuality and publish it.
#
Now that we have created our page. We are able to set up Textuality.
On your page dashboard, Click "Get Started". This has everything we need to get setup.
Your Textuality API key is your secret key. Do not share it with anyone.
#
Page Setup
#
.env Setup
First set up your .env file in the project route with the following:
TEXTUALITY_PAGE_ID=insert your page id here
TEXTUALITY_API_KEY=insert your api key here
#
NPM Packages
To get started with Textuality, you will need to install the following npm package:
npm install @textuality/client
Once we have this setup, Lets make a page for all our content.
#
General Blog Page
This is a general blog page that will show all the blogs that you have created on Textuality. This page will have a TTL of 1 hour per last update.
Lets call this /blog
"use client";
import { useEffect, useState } from "react";
export default function BlogPage() {
const [blogs, setBlogs] = useState<{ results: any[] } | null>(null);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
fetch("/api/textuality/full")
.then((res) => res.json())
.then((data) => {
if (data.error) {
setError(data.error);
} else {
setBlogs(data.blogs);
}
})
.catch((err) => {
setError(err.message);
});
}, []);
return (
<div className="w-full min-h-screen flex flex-col">
<main className="flex-grow h-screen py-12">
<div className="md:container mx-auto flex flex-col h-full px-4">
<div className="flex flex-col gap-1">
<h1 className="text-3xl font-bold text-start">Blogs</h1>
<div>
<a href="/work" className="text-neutral-400 text-sm">Powered by Textuality</a>
</div>
</div>
<div className="md:grid md:grid-cols-3 lg:grid-cols-4 gap-4 mt-4">
{error ? (
<p className="text-red-500">Error {error}</p>
) : (
blogs?.results?.map((blog, index) => (
<BlogCard
key={index}
title={blog.title}
authorpfp={blog.author.imageUrl}
authorName={blog.author.firstName + " " + blog.author.lastName}
date={new Date(blog._creationTime).toLocaleDateString()}
/>
))
)}
</div>
</div>
</main>
</div>
);
}
function BlogCard({ title, authorName, date, authorpfp }: { title: string; authorName: string; date: string; authorpfp: string }) {
return (
<div className="flex flex-col gap-4 border w-full px-4 py-4 rounded-md bg-white dark:bg-black/60">
<div className="flex flex-col gap-5">
<h1 className="text-2xl font-bold text-start">{title}</h1>
<div className="flex flex-row gap-2 items-center">
<div className="flex flex-row gap-2 items-center">
<img
src={authorpfp}
alt="Author"
className="h-7 border-2 w-7 p-0.5 rounded-full"
/>
<p className="text-neutral-400 text-sm">{authorName}</p>
</div>
•
<p className="text-neutral-400 text-sm">{date}</p>
</div>
</div>
</div>
);
}
This is a simple page that will show all the blogs that you have created on Textuality.
#
Specific Blog Page
This has significantly more data than the general blog page. For this blog page TTL will be 1 hour. This is to ensure that the data is always up to date and to lower your usage of the API.
We will also make a specific page for our blog posts. This is where all the content for that one blog will be shown.
For react we will call this /blog/[_blogid]
"use client"
import Footer from '@/components/footer/footer';
import Header from '@/components/header/header';
import { useEffect, useState } from 'react';
import Gatherer from '@/components/textuality/gatherer';
interface BlogProps {
params: {
_blogid: string;
};
}
export default function Blog({ params }: BlogProps) {
const { _blogid } = params;
const [blogs, setBlogs] = useState<any | null>(null);
useEffect(() => {
fetch(`/api/textuality/specific?blogid=${_blogid}`)
.then((res) => {
if (!res.ok) {
throw new Error("Network response was not ok");
}
return res.json();
})
.then((data) => {
if (data.error) {
console.error(data.error);
} else {
setBlogs(data.blogs);
}
})
.catch((err) => {
console.error('Error:', err);
});
}, [_blogid]);
return (
<div className="w-full min-h-screen flex flex-col">
<Header />
<main className="flex-grow h-screen py-12">
<div className="md:container mx-auto flex flex-col h-full px-4">
<div className="flex flex-col gap-1">
<a href="/work" className="text-neutral-400 text-sm">Powered by Textuality</a>
{blogs ? <Gatherer blogs={blogs} /> : <p>Loading...</p>}
</div>
</div>
</main>
<Footer />
</div>
);
}
#
Getting our API ready
Textuality has a simple API that you can use to get your content.
#
Full API Call
Lets make a file called /api/textuality/full/route.ts
We will use the following code:
import { NextRequest, NextResponse } from "next/server";
export async function GET(_req: NextRequest) {
const token = process.env.TEXTUALITY_API_KEY;
const pageid = process.env.TEXTUALITY_PAGE_ID;
const response = await fetch("http://textuality.hdev.uk/api/content/full/{pageid}", {
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
}
});
const data = await response.json();
if (data.error) {
return NextResponse.json({ error: data.error }, { status: 500 });
} else {
return NextResponse.json({ blogs: data }, { status: 200 });
}
}
#
Specific API Call
Lets make a file called /api/textuality/specific/route.ts
This will get the specific blog post that we want to show given the set parameters, In this case the blog id.
import { NextRequest, NextResponse } from 'next/server';
export async function GET(request: NextRequest) {
const token = process.env.TEXTUALITY_API_KEY;
const { searchParams } = new URL(request.url.replace('?=', '?'));
const id = searchParams.get('blogid');
if (!id) {
return NextResponse.json({ error: 'Missing blogid parameter' }, { status: 400 });
}
const response = await fetch(
`http://localhost:3001/api/content/exact/j977aj2be8w7wgyfdbsa5dhs8d768162/${id}`,
{
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`,
},
}
);
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
const data = await response.json();
console.log(data);
if (data.error) {
return NextResponse.json({ error: data.error }, { status: 500 });
}
return NextResponse.json({ blogs: data }, { status: 200 });
} else {
const text = await response.text();
return NextResponse.json({ error: 'Invalid response format', response: text }, { status: 500 });
}
}
#
Finish
All the technical stuff is done. 🥳
Now you can start creating content on Textuality, Publish it and it will show up on your website.