- Normally in any application you will create a project/organization and users and entities belonging to that organization
- Here we call that project/organization as a space
- We have a domain like
tidbitshub.com
ormyrubrics.com
- When we create a space, we create a subdomain for that space like
${space-id}.tidbitshub.com
or${space-id}.myrubrics.com
- We use the subdomain to show the content specific to that space.
- We only show the content of one space at a time. We never show the content of all spaces together.
- So based on the url, we determine the space and show the data of that space only.
- See
academy-ui/src/utils/space/getSpaceServerSide.tsx
to understand how UI makes a request to the server with the space host(domain in the url). - See how we then use that host to determine the space
academy-ui/src/app/api/spaces/route.ts
The first check in academy-ui/src/app/api/spaces/route.ts
is
const { searchParams } = new URL(req.url);
const domain = searchParams.get('domain');
const space = await prisma.space.findFirst({
where: {
domains: {
has: domain,
},
},
});
So on the server side, we can render the space on any domain. We can render the space on example-project.tidbitshub.com
or tidbitshubexample.com
or tidbitshub.example.com
. We just need to make sure that domain is added to the space.
We have some more logic to make it convenient to determine the space based on the domain. See the code in academy-ui/src/app/api/spaces/route.ts
Customers might want to use their own domain like realfinance.com
instead of realfinance.tidbitshub.com
or realfinance.myrubrics.com
because they don't their users to go to another domain. They want to keep the users on their domain.
So we provide the ability to map their domain to the space. This is done by adding a CNAME record in the DNS settings of the domain provider. They will have to do this themselves. On our side, we use Vercel's domain alias feature to make this work. See Here
A domain is like your website's main address (e.g., "example.com"), and a subdomain adds a word before this address to create a separate section (like "blog.example.com" or "docs.example.com"). Subdomains function independently from the main domain, allowing you to host completely different content or applications under the same overall website. For example, "blog.example.com" might feature news and articles, while "docs.example.com" could provide technical manuals or user guides. This setup helps organize content and services effectively, even though they're all part of the same primary domain.
Technically, domains and subdomains are managed through the Domain Name System (DNS), which translates human-readable names into IP addresses that computers use to communicate. The main domain (e.g., "example.com") is registered and associated with DNS records pointing to a server's IP address. Subdomains like "blog.example.com" or "docs.example.com" are created by adding a prefix to the main domain and configuring additional DNS records. These subdomains can point to the same server as the main domain or to entirely different servers and directories. This flexibility allows each subdomain to host different websites or applications, enabling completely separate content under the umbrella of the main domain.
There are some more features that are added to the space to make the product more useful:
- We want to have a different subdomain for each space. This architecture allows anyone to map a "custom" domain to their space(or our product + space).
- When a user goes to
realfinance.tidbitshub.com
, we determine the space based on the subdomain and show the content specific to that space. - See
academy-ui/src/utils/space/getSpaceServerSide.tsx
to understand how UI makes a request to the server passing the space host(domain in the url). - We have logic in
academy-ui/src/app/api/spaces/route.ts
to determine the space based on the domain.if (domain?.includes('.tidbitshub.org') || domain?.includes('.tidbitshub-localhost.org')) { const idFromDomain = domain.split('.')[0]; const space = await prisma.space.findFirst({ where: { id: idFromDomain, }, }); return NextResponse.json([space]); }
- Here we check if the domain includes
.tidbitshub.org
or.tidbitshub-localhost.org
and then we get the space based on the id in the domain. - The subdomain is the space id. So we get the space based on the space i.e. the subdomain.
- Many projects(example.com) have docs website or blogs. and they are hosted on a subdomain like
docs.example.com
orblog.example.com
. Similarly we want to provide the ability to hosttidbitshub
orrubrics
on a subdomain liketidbitshub.example.com
orrubrics.example.com
. - Here
tidbitshub.example.com
should use the theme ofexample.com
and the content shown should be specific to the project/spaceexample.com
. - We also provide the ability to have a parent(not subdomain) custom domain like
tidbitsexample.com
which will show a specific space's content and theme.
Example: We want an finance company "realfinance.com" to use our tidbits hub for sharing information with their customers, and we want them to use rubrics for their internal team.
- We will create a space for them called "realfinance"
- On
tidbitshub.com
, we will map this space torealfinance.tidbitshub.com
and show the content specific to the space "realfinance" - To make these subdomains work we use vercel's wildcard domain feature.
- Similarly, we will map the rubrics to
realfinance.myrubrics.com
and show the content specific to the space "realfinance"
- They would want to load tidbitshub when a users go to
tidbitshub.realfinance.com
and show the content specific to the space "realfinance". This is very similar to how many websites have a blog or docs website on a subdomain likedocs.realfinance.com
orblog.realfinance.com
- They don't want their customers to go to
realfinance.tidbitshub.com
but instead go totidbitshub.realfinance.com
- Many times people might want to use the main domain like
tisbitsrealfinance.com
instead ofrealfinance.tidbitshub.com
orrealfinance.myrubrics.com
- We will provide the ability to map the custom domain to the space.
Mapping of tisbitsrealfinance.com
to realfinance.tidbitshub.com
is done by adding a CNAME record in the DNS
settings of the domain provider. They will have to do this themselves. On our side, we use Vercel's domain alias feature
to make this work. See Here
- We always separate the data of each space and we never show data of all spaces together. We only show it one at a time for a particular url/space.
- We use
etc/hosts
file to map the domain to localhost. This file maps the domain to the localhost IP address. - On windows, the file is located at
C:\Windows\System32\drivers\etc\hosts
(or similar) - Here is an example of how we map the domain to localhost
127.0.0.1 alchemix.tidbitshub-localhost.org
- This will map the domain
alchemix.tidbitshub-localhost.org
to the localhost IP address.
Make sure to include the following mappings in your etc/hosts
file to test the spaces on local
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
# Marketing Sites
127.0.0.1 dodao-localhost.io
127.0.0.1 tidbitshub-localhost.org
127.0.0.1 myrubrics-localhost.com
# Academy Sites
127.0.0.1 dodao-localhost.academy
127.0.0.1 compound-localhost.education
127.0.0.1 uniswap-localhost.university
127.0.0.1 arbitrum-localhost.education
# Tidbits Sites
127.0.0.1 alchemix.tidbitshub-localhost.org
127.0.0.1 test-tidbits.tidbitshub-localhost.org
When testing creating or logging to different spaces from the marketing site(https://tidbitshub.org or myrubrics.com), When you login, you will see the list of spaces. You will see two lists
- One list will have the spaces that are created by the user
- The other list will have the spaces that the user is an admin of
We need to make sure we have a few mapping of the format in the etc/hosts
file
{space-id}.tidbitshub-localhost.org
Here space-id can be the id of the space already created or of the new space that will be created. On you local you can hardcode the space id of the new space to be created when testing space creation flow.
- How we determine the space based on the domain in the url
- How we show the content specific to the space based on the domain in the url
- How subdomains work
- How we use the subdomain to determine the space
- How subdomain is the space id
- How we use the custom domain to determine the space
- How to add a custom domain to the space
- How to add entries in the
etc/hosts
file to map the domain to localhost - How to map the domain to localhost on windows
- The important mappings to include in the
etc/hosts
file to test the spaces on local