What is Hygraph and how does it work with SvelteKit?
Hygraph is a GraphQL-native Headless CMS that enables users to model, manage, and deliver content for digital experiences. In the context of building a personal timeline with SvelteKit, Hygraph serves as the backend for content modeling (e.g., users, badges, activities, tags), while SvelteKit is used for the frontend to display and interact with that content. The integration is achieved via Hygraph's GraphQL Content API, which allows SvelteKit to fetch and render timeline data dynamically. Note: Hygraph is best suited for projects requiring flexible content modeling and API-driven delivery; teams needing a traditional page-based CMS may want to consider alternatives.
How do I model a personal timeline in Hygraph?
To model a personal timeline in Hygraph, you create content models such as Timeline User (with fields like name, username, job title, company, pronoun, location, avatar, banner, bio), User Badge (name, icon), Activity Detail (date, description), and Activity Tag (name, badge colour). Relationships are established using Reference fields, e.g., linking multiple User Badges and Activity Details to a Timeline User. Asset fields can include alt text and captions for accessibility. Note: This approach is flexible for custom timelines but may require manual setup for complex workflows.
How do I connect SvelteKit to Hygraph for content delivery?
SvelteKit connects to Hygraph using the GraphQL Content API. You define your API endpoint in an environment variable (e.g., VITE_CONTENT_API), use the graphql-request library to query data, and pass the results as props to your Svelte components. The API supports public access for content delivery, which can be enabled in Hygraph's settings. Note: Public API access should be configured carefully to avoid exposing sensitive data.
What are the main steps to deploy a SvelteKit project using Hygraph?
To deploy a SvelteKit project using Hygraph, you typically: 1) Set up your content models in Hygraph, 2) Build your SvelteKit frontend, 3) Connect to Hygraph's API for data, 4) Install a deployment adapter (e.g., @sveltejs/adapter-vercel for Vercel), and 5) Deploy to your chosen platform (Vercel, Netlify, Render, etc.). Note: Deployment steps may vary depending on your hosting provider and project requirements.
Features & Capabilities
What APIs does Hygraph provide for developers?
Hygraph offers several APIs: the GraphQL Content API for querying and manipulating content, the Management API for handling project structure (accessible via the Management SDK), the Asset Upload API for uploading files, and the MCP Server API for secure communication between AI assistants and Hygraph. For details, see the API Reference documentation. Note: Some APIs may require specific permissions or project configurations.
What integrations are available with Hygraph?
Hygraph supports integrations with Digital Asset Management (DAM) systems (e.g., Aprimo, AWS S3, Bynder, Cloudinary, Imgix, Mux, Scaleflex Filerobot), hosting and deployment platforms (Netlify, Vercel), Product Information Management (Akeneo), commerce solutions (BigCommerce), translation/localization (EasyTranslate), and others like Adminix and Plasmic. For a full list, visit the Hygraph Marketplace. Note: Integration availability may depend on your plan and project setup.
What technical documentation is available for Hygraph users?
Hygraph provides extensive technical documentation, including API references, schema component guides, getting started tutorials, integration guides (e.g., Mux, Akeneo, Auth0), and AI feature documentation. Access these resources at hygraph.com/docs. Note: Documentation for Hygraph Classic is also available for legacy users.
How does Hygraph perform in terms of speed and reliability?
Hygraph is optimized for high performance, featuring low-latency, high-throughput endpoints. The read-only cache endpoint delivers 3-5x latency improvement for content delivery. Performance is actively measured, with practical optimization advice available in the GraphQL Report 2024. Note: Actual performance may vary based on project complexity and API usage patterns.
Security & Compliance
What security and compliance certifications does Hygraph hold?
Hygraph is SOC 2 Type 2 compliant (since August 3, 2022), ISO 27001 certified for hosting infrastructure, and GDPR compliant. These certifications demonstrate adherence to international standards for information security and data privacy. For more details, visit the Hygraph Secure Features page. Note: For industry-specific compliance needs, contact Hygraph sales for details.
What security features are available in Hygraph?
Hygraph offers granular permissions, SSO integrations (OIDC/LDAP/SAML), audit logs, encryption in transit and at rest, regular backups with one-click recovery, and secure API policies (custom origin, IP firewalls). All endpoints use SSL certificates. Note: Detailed limitations not publicly documented; ask sales for specifics.
Use Cases & Benefits
Who can benefit from using Hygraph?
Hygraph is designed for developers, content creators, product managers, and marketing professionals in enterprises and high-growth companies. It is suitable for industries such as SaaS, eCommerce, media, healthcare, automotive, and more. Its flexibility supports both technical and non-technical users. Note: Teams seeking a traditional page-based CMS may want to consider alternatives.
What business impact can customers expect from using Hygraph?
Customers have reported faster time-to-market (e.g., Komax achieved 3x faster launches), improved customer engagement (Samsung saw a 15% increase), cost reduction, enhanced content consistency, and scalability. For example, AutoWeb increased website monetization by 20%, and Voi scaled multilingual content across 12 countries and 10 languages. Note: Results may vary based on implementation and use case. See Hygraph case studies for details.
What problems does Hygraph solve for content teams and developers?
Hygraph addresses operational inefficiencies (reducing developer dependency), modernizes legacy tech stacks, ensures content consistency for global teams, streamlines workflows, reduces operational costs, accelerates speed-to-market, and simplifies schema evolution. It also facilitates integration with third-party systems and optimizes content delivery with advanced caching. Note: Teams with highly specialized legacy workflows may require additional customization.
Customer Success & Social Proof
Can you share specific case studies or customer success stories with Hygraph?
Yes. Notable examples include Samsung (15% improved engagement), Komax (3x faster time-to-market), AutoWeb (20% increase in monetization), Voi (scaled content across 12 countries and 10 languages), and Dr. Oetker (enhanced digital experience with MACH architecture). For more, see Hygraph's case studies page. Note: Outcomes depend on project scope and implementation.
What feedback have customers given about Hygraph's ease of use?
Customers have praised Hygraph for its intuitive interface, quick adaptability, and accessibility for non-technical users. For example, Sigurður G. (CTO) noted the UI is intuitive, Anastasija S. (Product Content Coordinator) highlighted instant front-end updates, and Charissa K. (Senior CMS Specialist) emphasized the clear setup and localization features. Note: Some advanced features may require technical expertise.
Onboarding & Implementation
How long does it take to implement Hygraph and how easy is it to start?
Implementation time varies by project. For example, Top Villas launched in 2 months, Voi migrated from WordPress in 1-2 months, and Si Vale met aggressive deadlines in the initial phase. Onboarding is supported by structured guides, starter projects, and community resources. Sign up at app.hygraph.com/signup. Note: Complex migrations may require additional planning.
Industries & Use Cases
What industries are represented in Hygraph's case studies?
Hygraph's case studies cover SaaS, marketplaces, education technology, media and publication, healthcare, consumer goods, automotive, technology, fintech, travel and hospitality, food and beverage, eCommerce, agencies, online gaming, events & conferences, government, consumer electronics, engineering, and construction. Note: Industry-specific requirements may need custom configuration.
Recognition & Market Position
How is Hygraph recognized in the market?
Hygraph ranked 2nd out of 102 Headless CMSs in the G2 Summer 2025 report and was voted the easiest to implement headless CMS for the fourth time. These rankings are based on user reviews and implementation metrics. Note: Rankings may change over time; check G2 for the latest data.
Build a Personal Timeline with Hygraph and SvelteKit
Build and deploy your own personal timeline inspired by Polywork, with Hygraph and SvelteKit
Last updated by Scott
on Jan 21, 2026
Originally written by Scott
In this guide, I'll be making a personal timeline using Hygraph and SvelteKit, heavily inspired by Polywork’s approach to building personal profiles. If you’re wondering what Polywork is, it's a new platform where you can create a whole timeline of all your milestones and achievements and not just the roles or positions you have worked in before.
Here's what the end result will look like:
This option will give you that timeline you can add to your own site or have it as a stand-alone webpage.
This guide will cover getting your backend set up in Hygraph and creating your own content model of your timeline. I'll then go into displaying that content model on a web page.
If you've not used Hygraph before, you can take a look at the video playlists for how to Get Started with Hygraph and for further details, there's also the How to Hygraph playlist to check out.
Taking a look at a user's Polywork profile (timeline) I'll break that down into the relevant content types.
So a high-level overview of the content types I'm going to need will be:
User: name, current position, location, bio, and pronoun.
User Badges: what your interests are, JavaScript, Rock Climbing, etc.
Activity Detail: this is the detail of what you did, like 'started a side project'.
Tags: These are the tags you've applied to your activity, like 'Published a YouTube video'.
I'll now break down the content model as I'm going to create it in Hygraph. All of the Hygraph features I'll be using can be done with the community plan in this example.
Model Name: Timeline User
Field types
Name > Single line text
Username > Single line text > Validations > Set fields as unique
Job title > Single line text
Company > Single line text
Pronoun > Single line text
Location > Single line text
Avatar > Asset picker
Banner > Asset picker
Bio > Multi line text
Model Name: User Badge
Field types
Name > Single line text
Icon > Asset
Model Name: Activity Detail
Field types
Date > Date
Description > Rich text
Model Name: Activity Tag
Field types
Name > Single line text
Badge Colour > Color
Finally, for the content model, I will add some additional fields for the assets to include an alt text and a caption, Alt text as a 'Single line text' and the Caption as a 'Multi line text'.
Now that I have the models created, I can add in the relations for them with a Reference field:
Timeline User
User Badge > Model to reference > User badge > Allow multiple UserBadges per TimelineUser
Activity Details > Model to reference > Activity Detail > Allow multiple ActivityDetails per TimelineUser
If there were more than one user in the content model, I'd also check to Allow multiple Users per UserBadge and the same for the ActivityDetail. As it's only for me I'll keep it one to many for both.
Now there's a reverse field for Timeline User in the User Badge model and also for the Activity Detail.
User Badge
TimelineUser > Reference
Activity Detail
Timeline User > Reference
Activity Tag > Model to reference > Activity Tag > Allow multiple ActivityDetails per ActivityTag + Allow multiple ActivityTags per ActivityDetail
Activity Tag
Activity Details > Reference
If you're following along feel free to add your own validations to the fields, as it's only going to be small amounts of information I'm adding I'm going to leave them with the default validation.
Now that I have the content model created, I'll need to enable public access for the front end to use it.
In Settings > API access > Public Content API I'll enable the defaults by clicking the 'Yes, initialize defaults' button.
I'll copy some of the content from my Polywork profile and add it to my content model now.
For the front end, I'll be using SvelteKit, ultimately this can be any framework you are comfortable with. For the ease of scaffolding out the project, I'll be using SvelteKit along with DaisyUI which utilizes Tailwind and Tailwind prose.
As this is a single-page project and the main part of the project is on a single file, this can be done in any technology of your choosing.
I'll initialize the project with the following:
npm init svelte@next timeline
In my case I'm going to be choosing the following CLI options:
Skeleton project
No to TypeScript
No to ESLint
Yes to Prettier
Now if I pop open my text editor (VSCode), this is the basic project structure I have:
src/
│ └─ routes/
│ │ └─ index.svelte
│ └─ app.html
├─ static/
├─ .gitignore
├─ .npmrc
├─ .prettierignore
├─ .prettierrc
├─ jsconfig.json
├─ package.json
├─ README.md
└─ svelte.config.js
Time to install the dependencies, Tailwind and DaisyUI, along with Tailwind typography for great typography defaults it offers. Those along with GraphQL request, GraphQL.js (graphql) and Date FNS:
# add additional dependencies
npx svelte-add tailwindcss --jit
# 👆 this will configure Tailwind with Just In Time
npm i -D daisyui @tailwindcss/typography graphql-request graphql date-fns
npm i # shorthand for npm install
The Tailwind JIT compiler is optional, if you don't want to use it then you can remove the --jit from the npx command.
If you're following along, you'll notice svelte-add for Tailwind added some extra files to the project and changed others:
src/
│ └─ routes/
│ │ └─ __layout.svelte
│ └─ app.postcss
├─ postcss.config.js
├─ svelte.config.js
├─ tailwind.config.cjs
...rest mainly unchanged
Note the __layout.svelte was added and some additional config files for post CSS and Tailwind.
Popping open the __layout.svelte file I can see that the global CSS file has been added for the whole project:
<scriptcontext="module">
import'../app.postcss'
</script>
<main>
<slot/>
</main>
I'm going to leave this unchanged and focus on the routes/index.svelte file for the majority of the work.
I'll need to add the typography plugin and DaisyUI to the tailwind.config.js file:
As I mentioned earlier this will be a single file project, if you're following along and want to break it into more manageable parts, I'll leave that to you.
Now, I need to get the data from the Hygraph endpoint, as it's a public endpoint I can put it straight into the code, but I'll add this to an environment file so that it can be used from one place. I'll create a .env file and add in the endpoint there:
touch .env
In the newly created .env file, I'll create an environment variable and assign the project endpoint to it:
Not the VITE_ prefix is needed for Svelte to access the variable, Vite is the SvelteKit build tool and the VITE_ prefix is needed so the variable can be accessed on the client (browser).
Because I don't want to commit the .env file to GitHub I'll add .env to the .gitignore file, here's what my git ignore looks like:
.DS_Store
node_modules
/.svelte-kit
/package
.env
Now that I have the endpoint available to me via Vite, I can go about getting the data to use in the project.
I'll add a <script context="module"> to the top of my index.svelte file, this will fetch the data before the page loads.
In that block, I'm going to define a new GraphQLClient as hygraph then I'll bring in the API endpoint to use in the client.
I'll need to define a query to retrieve all the timeline information to use. I'll come onto that next for now. I'll define an empty gql tag to be passed to the client. The results from that query are then returned as props for the client to use.
Now, I need to define the query needed to pull all the user and timeline information.
In the Hygraph API playground I'll define all the fields I need:
{
timelineUser(where:{username:"spences10"}){
id
name
username
jobTitle
company
pronoun
location
bio
avatar{
url
altText
}
banner{
url
altText
}
userBadges{
name
}
activityDetails(orderBy:createdAt_DESC){
date
description{
html
}
activityTags{
id
name
badgeColour{
hex
}
}
}
}
}
That query can go into the empty gql tag I had in the previous code example. Note that I have hardcoded the timeline user with my username timelineUser(where: { username: "spences10" }), if you have more than one user then this would be a good time to look into SvelteKit routing. I won't be covering that in this post but you can check out the documentation if you want to take it to the next level with this project.
Sweet! So now that I have the data available to me to use in the client, I can now focus on displaying that data.
I'll add a <script> directly under the closing <script context="module"> tag. This is where I can access the props returned by the <script context="module"> block.
I'll define export let timelineUser prop then destructure all the variables I'll need from it, and notice all the variables match up to the GraphQL query.
Now I'll add in some containers for the basics card (username, job title etc...) and the activity list, then create a component for those to be used in the index.svelte file:
I'll create a new folder and files for the basics card and the activities components now in the terminal:
mkdir src/lib
touch src/lib/basics.svelte
touch src/lib/activities.svelte
In the basics.svelte file I'm going to need to import some props, I'll start with the avatar and the name. For this, I'll add the props inside some <script> tags and scaffold out the markup for the avatar and the name:
Next up for the basics card is adding in any user badges, I'll use the Svelte 'if' directive {#if userBadges} to check if there are any badges to render then looping over each badge in the userBadges props if there is with the Svelte 'each' directive {#each userBadges as { name }}:
Last up is adding in the Multi line text for the bio, note I've added in some JavaScript to take care of any line breaks with {@html bio.split('\n').join('<br />')}, the @html is to render HTML directly if this is left out it will show the HTML tags in the markup:
In Svelte, if the name of the prop being passed is the same as what's being expected by the component then there's no need to define the name of the prop, so avatar={avatar} becomes {avatar} neat eh?
Now to go through the same process for the activities card, I've already got the file so in src/lib/activities.svelte I'll start scaffolding out what's needed there, this one is a bit simpler as it's only taking the activityDetails prop:
<script>
import { format } from 'date-fns'
export let activityDetails
</script>
<section>
{#if activityDetails}
{#each activityDetails as activity}
<section class="border mb-4 card shadow">
<div class="card-body">
{#if activity.activityTags}
{#each activity.activityTags as { name, badgeColour }}
Again, there's a lot of use of the Svelte directives for 'if' and 'each' here along with the @html tag. I'll break it down a bit into what's going on here. The first 'if' is to conditionally render any activities if there are any and the next is to check if there are any activity tags applied to the activity.
If there are tags, they are being looped over to add to the activity. I'm using date-fns to format the date as I like then finally rendering out the activity detail!
Now, I can import this component into my index.svelte file at the top of the file like with the basics card:
<script context="module">
import Activities from '$lib/activities.svelte'
import Basics from '$lib/basics.svelte'
And that's it! 😅
If you want to check out the code, I've made it available on GitHub.
I'll be deploying this project to Vercel. There are other providers available like Render and Netlify if you prefer, but for the ease of setting up, I'll be using Vercel.
I'll need to install a SvelteKit adapter for Vercel, I'll install it with the following command:
npm i -D @sveltejs/adapter-vercel@next
Note the @next as part of the install.
Next up, I'll need to add the adapter to my svelte.config.js file, here's what mine looks like:
importadapterfrom'@sveltejs/adapter-vercel'
importpreprocessfrom'svelte-preprocess'
/** @type {import('@sveltejs/kit').Config} */
const config ={
kit:{
// hydrate the <div id="svelte"> element in src/app.html
target:'#svelte',
adapter:adapter(),
},
preprocess:[
preprocess({
postcss:true,
}),
],
}
exportdefault config
// Workaround until SvelteKit uses Vite 2.3.8 (and it's confirmed to fix the Tailwind JIT problem)
const mode = process.env.NODE_ENV
const dev = mode ==='development'
process.env.TAILWIND_MODE= dev ?'watch':'build'
From here, I can use the Vercel CLI and use vc from the command line to deploy it. I have also the added option to link the Vercel project to a GitHub repo.
If you're using SvelteKit and want to use a different hosting provider there are several adapters available via the SvelteKit documentation.
That's it, thanks for reading, if you want to take a look at the code for this you can find it over on my GitHub and the working example can be found here.
Blog Author
Scott Spence
Developer Advocate @Hygraph • Learner of things • Jamstack • Svelte
Share with others
Sign up for our newsletter!
Be the first to know about releases and industry news and insights.
Build a Personal Timeline with Hygraph and SvelteKit
Build and deploy your own personal timeline inspired by Polywork, with Hygraph and SvelteKit
Last updated by Scott
on Jan 21, 2026
Originally written by Scott
In this guide, I'll be making a personal timeline using Hygraph and SvelteKit, heavily inspired by Polywork’s approach to building personal profiles. If you’re wondering what Polywork is, it's a new platform where you can create a whole timeline of all your milestones and achievements and not just the roles or positions you have worked in before.
Here's what the end result will look like:
This option will give you that timeline you can add to your own site or have it as a stand-alone webpage.
This guide will cover getting your backend set up in Hygraph and creating your own content model of your timeline. I'll then go into displaying that content model on a web page.
If you've not used Hygraph before, you can take a look at the video playlists for how to Get Started with Hygraph and for further details, there's also the How to Hygraph playlist to check out.
Taking a look at a user's Polywork profile (timeline) I'll break that down into the relevant content types.
So a high-level overview of the content types I'm going to need will be:
User: name, current position, location, bio, and pronoun.
User Badges: what your interests are, JavaScript, Rock Climbing, etc.
Activity Detail: this is the detail of what you did, like 'started a side project'.
Tags: These are the tags you've applied to your activity, like 'Published a YouTube video'.
I'll now break down the content model as I'm going to create it in Hygraph. All of the Hygraph features I'll be using can be done with the community plan in this example.
Model Name: Timeline User
Field types
Name > Single line text
Username > Single line text > Validations > Set fields as unique
Job title > Single line text
Company > Single line text
Pronoun > Single line text
Location > Single line text
Avatar > Asset picker
Banner > Asset picker
Bio > Multi line text
Model Name: User Badge
Field types
Name > Single line text
Icon > Asset
Model Name: Activity Detail
Field types
Date > Date
Description > Rich text
Model Name: Activity Tag
Field types
Name > Single line text
Badge Colour > Color
Finally, for the content model, I will add some additional fields for the assets to include an alt text and a caption, Alt text as a 'Single line text' and the Caption as a 'Multi line text'.
Now that I have the models created, I can add in the relations for them with a Reference field:
Timeline User
User Badge > Model to reference > User badge > Allow multiple UserBadges per TimelineUser
Activity Details > Model to reference > Activity Detail > Allow multiple ActivityDetails per TimelineUser
If there were more than one user in the content model, I'd also check to Allow multiple Users per UserBadge and the same for the ActivityDetail. As it's only for me I'll keep it one to many for both.
Now there's a reverse field for Timeline User in the User Badge model and also for the Activity Detail.
User Badge
TimelineUser > Reference
Activity Detail
Timeline User > Reference
Activity Tag > Model to reference > Activity Tag > Allow multiple ActivityDetails per ActivityTag + Allow multiple ActivityTags per ActivityDetail
Activity Tag
Activity Details > Reference
If you're following along feel free to add your own validations to the fields, as it's only going to be small amounts of information I'm adding I'm going to leave them with the default validation.
Now that I have the content model created, I'll need to enable public access for the front end to use it.
In Settings > API access > Public Content API I'll enable the defaults by clicking the 'Yes, initialize defaults' button.
I'll copy some of the content from my Polywork profile and add it to my content model now.
For the front end, I'll be using SvelteKit, ultimately this can be any framework you are comfortable with. For the ease of scaffolding out the project, I'll be using SvelteKit along with DaisyUI which utilizes Tailwind and Tailwind prose.
As this is a single-page project and the main part of the project is on a single file, this can be done in any technology of your choosing.
I'll initialize the project with the following:
npm init svelte@next timeline
In my case I'm going to be choosing the following CLI options:
Skeleton project
No to TypeScript
No to ESLint
Yes to Prettier
Now if I pop open my text editor (VSCode), this is the basic project structure I have:
src/
│ └─ routes/
│ │ └─ index.svelte
│ └─ app.html
├─ static/
├─ .gitignore
├─ .npmrc
├─ .prettierignore
├─ .prettierrc
├─ jsconfig.json
├─ package.json
├─ README.md
└─ svelte.config.js
Time to install the dependencies, Tailwind and DaisyUI, along with Tailwind typography for great typography defaults it offers. Those along with GraphQL request, GraphQL.js (graphql) and Date FNS:
# add additional dependencies
npx svelte-add tailwindcss --jit
# 👆 this will configure Tailwind with Just In Time
npm i -D daisyui @tailwindcss/typography graphql-request graphql date-fns
npm i # shorthand for npm install
The Tailwind JIT compiler is optional, if you don't want to use it then you can remove the --jit from the npx command.
If you're following along, you'll notice svelte-add for Tailwind added some extra files to the project and changed others:
src/
│ └─ routes/
│ │ └─ __layout.svelte
│ └─ app.postcss
├─ postcss.config.js
├─ svelte.config.js
├─ tailwind.config.cjs
...rest mainly unchanged
Note the __layout.svelte was added and some additional config files for post CSS and Tailwind.
Popping open the __layout.svelte file I can see that the global CSS file has been added for the whole project:
<scriptcontext="module">
import'../app.postcss'
</script>
<main>
<slot/>
</main>
I'm going to leave this unchanged and focus on the routes/index.svelte file for the majority of the work.
I'll need to add the typography plugin and DaisyUI to the tailwind.config.js file:
As I mentioned earlier this will be a single file project, if you're following along and want to break it into more manageable parts, I'll leave that to you.
Now, I need to get the data from the Hygraph endpoint, as it's a public endpoint I can put it straight into the code, but I'll add this to an environment file so that it can be used from one place. I'll create a .env file and add in the endpoint there:
touch .env
In the newly created .env file, I'll create an environment variable and assign the project endpoint to it:
Not the VITE_ prefix is needed for Svelte to access the variable, Vite is the SvelteKit build tool and the VITE_ prefix is needed so the variable can be accessed on the client (browser).
Because I don't want to commit the .env file to GitHub I'll add .env to the .gitignore file, here's what my git ignore looks like:
.DS_Store
node_modules
/.svelte-kit
/package
.env
Now that I have the endpoint available to me via Vite, I can go about getting the data to use in the project.
I'll add a <script context="module"> to the top of my index.svelte file, this will fetch the data before the page loads.
In that block, I'm going to define a new GraphQLClient as hygraph then I'll bring in the API endpoint to use in the client.
I'll need to define a query to retrieve all the timeline information to use. I'll come onto that next for now. I'll define an empty gql tag to be passed to the client. The results from that query are then returned as props for the client to use.
Now, I need to define the query needed to pull all the user and timeline information.
In the Hygraph API playground I'll define all the fields I need:
{
timelineUser(where:{username:"spences10"}){
id
name
username
jobTitle
company
pronoun
location
bio
avatar{
url
altText
}
banner{
url
altText
}
userBadges{
name
}
activityDetails(orderBy:createdAt_DESC){
date
description{
html
}
activityTags{
id
name
badgeColour{
hex
}
}
}
}
}
That query can go into the empty gql tag I had in the previous code example. Note that I have hardcoded the timeline user with my username timelineUser(where: { username: "spences10" }), if you have more than one user then this would be a good time to look into SvelteKit routing. I won't be covering that in this post but you can check out the documentation if you want to take it to the next level with this project.
Sweet! So now that I have the data available to me to use in the client, I can now focus on displaying that data.
I'll add a <script> directly under the closing <script context="module"> tag. This is where I can access the props returned by the <script context="module"> block.
I'll define export let timelineUser prop then destructure all the variables I'll need from it, and notice all the variables match up to the GraphQL query.
Now I'll add in some containers for the basics card (username, job title etc...) and the activity list, then create a component for those to be used in the index.svelte file:
I'll create a new folder and files for the basics card and the activities components now in the terminal:
mkdir src/lib
touch src/lib/basics.svelte
touch src/lib/activities.svelte
In the basics.svelte file I'm going to need to import some props, I'll start with the avatar and the name. For this, I'll add the props inside some <script> tags and scaffold out the markup for the avatar and the name:
Next up for the basics card is adding in any user badges, I'll use the Svelte 'if' directive {#if userBadges} to check if there are any badges to render then looping over each badge in the userBadges props if there is with the Svelte 'each' directive {#each userBadges as { name }}:
Last up is adding in the Multi line text for the bio, note I've added in some JavaScript to take care of any line breaks with {@html bio.split('\n').join('<br />')}, the @html is to render HTML directly if this is left out it will show the HTML tags in the markup:
In Svelte, if the name of the prop being passed is the same as what's being expected by the component then there's no need to define the name of the prop, so avatar={avatar} becomes {avatar} neat eh?
Now to go through the same process for the activities card, I've already got the file so in src/lib/activities.svelte I'll start scaffolding out what's needed there, this one is a bit simpler as it's only taking the activityDetails prop:
<script>
import { format } from 'date-fns'
export let activityDetails
</script>
<section>
{#if activityDetails}
{#each activityDetails as activity}
<section class="border mb-4 card shadow">
<div class="card-body">
{#if activity.activityTags}
{#each activity.activityTags as { name, badgeColour }}
Again, there's a lot of use of the Svelte directives for 'if' and 'each' here along with the @html tag. I'll break it down a bit into what's going on here. The first 'if' is to conditionally render any activities if there are any and the next is to check if there are any activity tags applied to the activity.
If there are tags, they are being looped over to add to the activity. I'm using date-fns to format the date as I like then finally rendering out the activity detail!
Now, I can import this component into my index.svelte file at the top of the file like with the basics card:
<script context="module">
import Activities from '$lib/activities.svelte'
import Basics from '$lib/basics.svelte'
And that's it! 😅
If you want to check out the code, I've made it available on GitHub.
I'll be deploying this project to Vercel. There are other providers available like Render and Netlify if you prefer, but for the ease of setting up, I'll be using Vercel.
I'll need to install a SvelteKit adapter for Vercel, I'll install it with the following command:
npm i -D @sveltejs/adapter-vercel@next
Note the @next as part of the install.
Next up, I'll need to add the adapter to my svelte.config.js file, here's what mine looks like:
importadapterfrom'@sveltejs/adapter-vercel'
importpreprocessfrom'svelte-preprocess'
/** @type {import('@sveltejs/kit').Config} */
const config ={
kit:{
// hydrate the <div id="svelte"> element in src/app.html
target:'#svelte',
adapter:adapter(),
},
preprocess:[
preprocess({
postcss:true,
}),
],
}
exportdefault config
// Workaround until SvelteKit uses Vite 2.3.8 (and it's confirmed to fix the Tailwind JIT problem)
const mode = process.env.NODE_ENV
const dev = mode ==='development'
process.env.TAILWIND_MODE= dev ?'watch':'build'
From here, I can use the Vercel CLI and use vc from the command line to deploy it. I have also the added option to link the Vercel project to a GitHub repo.
If you're using SvelteKit and want to use a different hosting provider there are several adapters available via the SvelteKit documentation.
That's it, thanks for reading, if you want to take a look at the code for this you can find it over on my GitHub and the working example can be found here.
Blog Author
Scott Spence
Developer Advocate @Hygraph • Learner of things • Jamstack • Svelte
Share with others
Sign up for our newsletter!
Be the first to know about releases and industry news and insights.