Introducing Hashtree - Link tree for all hashnode users ✌
Create an amazing linktree with your hashnode username!
Hello Devs 👋
This is Savio here. I'm young dev with an intention to enhance as a successful web developer. I love building web apps with React. I have proved my superiority in frontend technologies.
Little flashback
I was introduced to hashnode API few days backs, I was so excited and felt to make an app using the amazing hashnode graphql API.
The docs were easy to understand, I was a total beginner to the world of graphql. So, it took me some time to learn the graphql and it client works. I felt it comfortable to use Appolo than fetch. And yeah, after some weeks of learning, I was able to code Hashtree
Introducing Hashtree
Hashtree is a simple app that will generate an amazing fully responsive linktree for you to share on social media sites like Instagram, Twitter, Facebook, etc. It is so easy that you just have to tupe your hashnode username and select a theme, an amazing linktree will be generated for you! 🙌
🎉 Features
So far, Hashtree is rich with the following features
- Fully responsive
- Multiple Themes
- Lightning Fast
- Great animations
- Icon support
- Super UI
- PWA, Installable
- Open Source, fully free to use
💻 Built with
- Hashnode API
- React
- Box Icons for icons
- Material UI: for styling and effects
- Animate.css: for smooth Animations
- react-router-dom: for routing
- Vercel: for hosting
🎸 Planning, Building, and Deploying
As I said, hashnode API is the only source for the information. I got the data from the hashnode graphql API by following the code snippet.
query($username: String!) {
user(username: $username) {
_id
name
tagline
photo
publicationDomain
socialMedia {
twitter
github
stackoverflow
linkedin
google
website
facebook
}
}
}
and as the query variable, lets pass the username. Like this
{ "username": "saviomartin" }
this will perfectly work in the Hashnode API playground. Its that simple. So, to get the data in our app, I used appolo. It makes everything super easy to build up.
I also created components to make stop duplication, so here goes the code I used 👇
query.js
import { gql } from "@apollo/client";
const USER = gql`
query($username: String!) {
user(username: $username) {
_id
name
tagline
photo
publicationDomain
socialMedia {
twitter
github
stackoverflow
linkedin
google
website
facebook
}
}
}
`;
export default USER;
Main.js
import React from "react";
import { useQuery } from "@apollo/client";
import USER from "./query";
import { useParams } from "react-router-dom";
import Header from "./components/Header";
import Link from "./components/Links";
import Footer from "./components/Footer";
const Main = () => {
let params = useParams();
const username = params.username;
const theme = params.theme;
const { loading, error, data } = useQuery(USER, {
variables: { username }
});
if (loading)
return (
<div className={`loader flex ${theme}`}>
<div class="spinner"></div>
</div>
);
if (error) return <p>Something went wrong</p>;
if (data) {
return (
<div className={`main flex ${theme}`}>
<Header
name={data.user.name}
profileImg={data.user.photo}
tagline={data.user.tagline}
/>
<div className="helper flex">
{data.user.socialMedia.twitter && (
<Link
linkTitle="Twitter"
linkIcon="bxl-twitter"
link={data.user.socialMedia.twitter}
/>
)}
{data.user.socialMedia.github && (
<Link
linkTitle="Github"
linkIcon="bxl-github"
link={data.user.socialMedia.github}
/>
)}
{data.user.socialMedia.linkedin && (
<Link
linkTitle="Linkedin"
linkIcon="bxl-linkedin"
link={data.user.socialMedia.linkedin}
/>
)}
{data.user.socialMedia.facebook && (
<Link
linkTitle="facebook"
linkIcon="bxl-facebook"
link={data.user.socialMedia.facebook}
/>
)}
{data.user.socialMedia.stackoverflow && (
<Link
linkTitle="Stackoverflow"
linkIcon="bxl-stackoverflow"
link={data.user.socialMedia.stackoverflow}
/>
)}
{data.user.socialMedia.google && (
<Link
linkTitle="Google"
linkIcon="bxl-google"
link={data.user.socialMedia.google}
/>
)}
{data.user.socialMedia.website && (
<Link
linkTitle="Website"
linkIcon="bx-world"
link={data.user.socialMedia.website}
/>
)}
<Footer />
</div>
</div>
);
}
};
export default Main;
Yeah, thats it. We'll now get the data and return our linktree. If we try to console the data it'll we like 👇
{
"user": {
"__typename": "User",
"_id": "5f9d514cb309125fbb61a2c1",
"name": "Savio Martin",
"tagline": "Focused on Frontend, love backend too",
"photo": "https://cdn.hashnode.com/res/hashnode/image/upload/v1615368428147/TMHA5E7Gq.jpeg",
"publicationDomain": "savio.xyz",
"socialMedia": {
"__typename": "SocialMedia",
"twitter": "https://twitter.com/saviomartin7",
"github": "https://github.com/saviomartin",
"stackoverflow": "",
"linkedin": "https://www.linkedin.com/in/saviomartin/",
"google": null,
"website": "https://savio.works/",
"facebook": ""
}
}
}
I hope you now got an good understanding of how to use Hashnode graphql API
The data we have entered in our hashnode profile settings is the major source of information.
If you want to edit your data, just go to your settings and edit it. Its so fast 🚀
Feel free to try out: http://hashtree.vercel.app/
Star the repo ⭐ github.com/saviomartin/hashtree
Challenges
Challenge | Solution |
Change different URLs without loading | Used react-router-dom |
Fast fetching data | used Appolo |
Make the app 100/100 on PWA Check | Optimised app, solved errors |
Responsiveness of the app | Used @media queries |
Solving doubts | Asked in the hashnode discord server |
✨️ What's next
These are some of the features, I currently have in mind.
- More themes
- Set background image
- Setting page, where you could edit your styles
- Dark mode support
🛡️ Licensed under MIT
👀 Wrapping Up
Yeah, that's a wrap. Hope you enjoyed Hash tree. Feel free to use the app. Do not hesitate to share your feedback. Share on Twitter, tag me @saviomartin7
Star the repo ⭐ github.com/saviomartin/hashtree
🌎 Lets connect
🎸 Feedback
Hash tree needs your feedback to improve. Help Hash tree by adding your valuable reviews 💖