I've been relatively quiet on HIVE lately, this is because the rise of AI has kept me immersed in a world of new tools and technologies. I have mainly been working on building website projects to integrate with HIVE, keep reading to the end of this post and I will share a link to the site I'm working on. Amidst my busy schedule, I'm eager to share some of the intriguing and valuable insights I've learned along the way. I was quite surprised at how involved it was adding a simple one-page Termly privacy policy to my Nextjs web app. so here's the lowdown of the various processes involved below. Let's dive in.
Step 1. Sign up with Termly for free here: https://app.termly.io/
Step 2. Select the type of Terms and conditions that match your site by letting Termly scan your entire website. Next, you will be prompted with various questions, once you answer all the questions Termly will create your specific page.
Step 3. Copy the HTML code provided by Termly by clicking ADD TO WEBSITE, and then click, COPY TO CLIPBOARD. Be sure to paste it in a text editor, or notes, somewhere you can separate the two major parts. It’s a huge file, so don’t be intimidated, the top is the style sheet (in the green square below), and the bottom of the file is the HTML portion.
...
Step 4. Convert the HTML section to JSX for working in NextJS. I found a nifty site to do this, it’s called https://transform.tools/html-to-jsx
Remember to only convert the HTML to JSX, and leave the style sheet portion alone for now.
Step 5. Now, it’s time to open up our Next.js app and create a component, in the pages directory. This is where we will integrate the converted JSX code we generated in the previous step, along with its associated styles that we initially copied directly from Termly. Since Termly provides a separate stylesheet for styling the privacy policy, there are a few options for integrating it into your Next.js app. You can either use a global stylesheet and make sure to import it to your page, or simply create a component-specific style sheet, which is the route I took for this example. Later on, if I find out that the style sheets are not specific to each Termly policy I could pull the styles out and use one global stylesheet to service all the pages. Here is the in-line component-specific style sheet component code snippet example that I used below:
'use client'
import React from 'react';
const PrivacyPolicy = () => (
<div>
<style jsx>{`
[data-custom-class='body'], [data-custom-class='body'] * {
background: transparent !important;
}
/* ... other styles ... */
`}</style>
{/* Your component content */}
</div>
);
export default PrivacyPolicy;
What you want to do is copy the style sheet ( I made a green square around the pertinent part in the image above) in-between the <style jsx>{`
copy styles here `}</style>
tags.
Next, paste your JSX code where it says Your Component Content in that same component code snippet. This part is easy, it’s just a bunch of div tags, here is the view of the bottom of the file in my code editor. Look how long this file is, I think it’s reaching the limit of Visual Studio code… lol Working with these long files can be a challenge in themselves.
Step 6. Add a little padding to the very first div tag.
}</style>
<div data-custom-class="body" style={{ padding: '0 60px' }}>
<div>
I used 60 pixels because the page was coming out close to the left and right margin by default. Refer to image…
Step 7. At this point you should still be seeing error messages like Property 'bdt' does not exist on type 'JSX.IntrinsicElements'. Property 'bdt' does not exist on type 'JSX.IntrinsicElements'. This is ok, that means you are on the right track. The error message is related to TypeScript and JSX (JavaScript XML). This error typically occurs when you're trying to use a property or attribute called 'bdt' on a JSX element, but TypeScript can't find it in the type definitions for JSX.IntrinsicElements. Therefore in this case, since Termly uses BDT we must Extend JSX.IntrinsicElements.
Since 'bdt' is not a standard HTML attribute and we want to use it in JSX, we can extend the JSX.IntrinsicElements type to include our custom properties. This is often done by creating a global.d.ts file and declaring the additional properties there. So to fix this issue we must add a file named global.d.ts to the root (main folder) of our project. If you don't already have one, create this file now and paste the following code snippet into it to tell TypeScript that 'bdt' is a valid property for JSX elements.
// global.d.ts
declare namespace JSX {
interface IntrinsicElements {
// Add your custom properties here
bdt: any;
}
}
Step 8.
Include in tsconfig.json:
Ensure that your tsconfig.json file includes the global.d.ts file in the "files" or "include" section. If you don't have a tsconfig.json file, you may need to create one.
{
"compilerOptions": {
// Your compiler options here
},
"files": [
"global.d.ts"
],
// OR
"include": [
"global.d.ts",
// Other files and directories
]
}
Step 9. Build your app. You can check your new page in the development server, however, it won’t compile yet because of one last issue, and the issue has to do with some characters that https://transform.tools/html-to-jsx may have missed. Online tools like html-to-jsx often do a great job of converting HTML to JSX, but they might not catch every single minute detail, especially when it comes to escaping characters. It's always a good practice to review the output and make any necessary adjustments, especially when dealing with characters that have special meaning in JSX or HTML.
In these long-winded privacy notices, Termly likes to use a lot of quotes and apostrophes, and the compiler does not like it. If you see errors like the ones below, it’s time to pat yourself on the back because it means you are on the home stretch. Here is what you may see when getting to this stage while working on a Termly policy page…
Failed to compile.
./src/app/pages/privacypolicy/page.tsx
87:47 Error: `"` can be escaped with `"`, `“`, `"`, `”`. react/no-unescaped-entities
87:68 Error: `"` can be escaped with `"`, `“`, `"`, `”`. react/no-unescaped-entities
87:70 Error: `"` can be escaped with `"`, `“`, `"`, `”`. react/no-unescaped-entities
88:31 Error: `"` can be escaped with `"`, `“`, `"`, `”`. react/no-unescaped-entities
88:36 Error: `"` can be escaped with `"`, `“`, `"`, `”`. react/no-unescaped-entities
88:57 Error: `"` can be escaped with `"`, `“`, `"`, `”`. react/no-unescaped-entities
93:46 Error: `"` can be escaped with `"`, `“`, `"`, `”`.
info - Need to disable some ESLint rules? Learn more here: https://nextjs.org/docs/basic-features/eslint#disabling-rules
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
The error messages above are related to ESLint and the react/no-unescaped-entities rule. This rule is designed to catch unescaped HTML entities within JSX to prevent certain types of XSS (cross-site scripting) vulnerabilities. The error message indicates that you have unescaped characters (like quotes or apostrophes) in your JSX, and it's suggesting to escape them using HTML entities.
To address this issue simply Escape the Characters: Identify the locations in your JSX where the unescaped characters are present, and replace them with their corresponding HTML entities. Luckily with Visual Studio Code, you can just hover over each error and a link will pop up and take you there.
For example: to escape these quotes with "
<bdt className="block-component" />"<strong>we</strong>," "
<strong>us</strong>," or "<strong>our</strong>"
You would change the above line of code to the line below…..
<bdt className="block-component" />"<strong>we</strong>," "<strong>us</strong>," or "<strong>our</strong>"
So do this about 50 more times because that’s how many there will probably be. I’m sure there will be some genius out there who knows how to find them all way quicker, if you know how please be sure to leave a comment down below.
Here's a simpler example. If you need to escape apostrophes in the word "Consumer's" within JSX, you can use the HTML entity ’ for the apostrophe. Here's how you can modify the code:
<span data-custom-class="body_text">
<u>
Right to Non-Discrimination for the Exercise of a Consumer’s Privacy Rights
</u>
</span>
By now you should get the gist of escaping special characters to get your pages to work.. After escaping all the characters in the error log, that’s it, we’re finished. And here's what the finished page looks like on my project, you can check it out at the link below:
https://heliosmarket.io/pages/privacypolicy
HeliosMarket.io is the website I've been working on, it has been my playground for exploring the endless possibilities of what I can create with AI by my side. Looking ahead, the roadmap for HeliosMarket can be long, it extends to the integration of HIVE payments, and much more. Thanks to the availability of AI, much more is possible than I ever dreamed, so stay tuned and follow me for tips and tricks I learn along the way. Any questions, feel free to leave them in the comments section below.
@tipu curate
Upvoted 👌 (Mana: 22/52) Liquid rewards.
Excellent informative post I am waiting for your posting
$WINE
You may wanna check what people are doing with your stake: https://peakd.com/hive-131951/@helios.voter/re-danielvehe-s6poia
Bro I am helios.voter, thanks for the tip! Just because someone accuses someone else of doing something doesn't make them right. Daniel is spreading false accusations and slandering my project so I was defending our community with our stake. Thanks for trying to help but nothing is going on.
If someone goes and reports a project or account to hivewatcher it doesn't give people the right to go on a downvote spree and threaten to downvote someone forever, especially when they don't have a history of starting drama or wanting bad things for hive, on the contrary. Furthermore, the curation of helios.voter is really questionable, so many accounts with close to no comments posting questionable content if it's original or just copy-pasted/spun, even if it was original if there is no consumption since there are no followers/readers and the authors aren't making an effort it doesn't justify the rewards. Not even going to get into the basis of what the token does and what you can do with it, just a bad idea in general for proof of brain.
I get what you're saying. We also check users & content, I thought everyone was legit. I haven't concentrated on users' comments because until now I didn't see that link. I write original posts and I never comment anymore, so maybe that's why I didn't get that association. It's all about curation so we are also very careful where our votes are heading. We stopped spamming posts with our automated comments, as I recall it was one of your posts about not being able to find the real comments at the end of a post that gave us that idea, and that's the reason for our automated post per day, besides showing token statistics.
It was a good idea, however, that user Daniel kept downvoting our automated posts and later started complaining about them.
You also have automated posts, if someone upvotes those posts it's not your problem right?
We didn't initiate that drama, we watched and waited for a long time before flagging back a little. We're not going to flag him forever, I'm gonna leave Daniel alone, that comment just came out of a moment of comment rage.
We won't initiate any more drama as well. But when someone keeps trying to make drama from our patience that's unfair.
If you have any proof of any of our users spinning up old posts or someone else's work, please report it and we will blacklist them immediately. Normally we rely on the spaminator list to automatically block out bad users, not sure why these users you mention that don't comment have slipped through the cracks when Hivewatchers gets 350 a day to do this.
Thanks for the input, we are working on screening the posts we curate much more carefully.
Take a look at the last few comments I've left, it's hard to understand how posts and users like those constantly receive 100% votes from you.