There are three identified scenarios. ## First scenario The user uses a desktop. They click on a company, which is opened in the side panel. They click on a tab, like "Tasks". The user chooses to open the record in fullscreen. The "Tasks" tab is opened by default in the fullscreen record page. If the user refreshes the page, the default tab is shown: "Timeline". **This was the behavior on the show pages, and I kept it.** If we wanted to show the "Tasks" tab here, we would have to put the id of the "Tasks" tab in the URL hash when we open the record in fullscreen and an active tab id is already set. https://github.com/user-attachments/assets/205776ac-9ad7-4e79-af9a-6b44360a5d77 ## Second scenario The user uses a desktop or a mobile device and interacts with a company record. They click on a tab. If they refresh, the selected tab will be displayed by default. ### Desktop https://github.com/user-attachments/assets/d4e1908b-a591-42f6-bb82-5aec592e2778 ### Mobile https://github.com/user-attachments/assets/7bab73cc-a2ff-4ce8-9bc6-325efef2d500 ## Third scenario The user uses a desktop. They click on a dashboard, which is opened in fullscreen mode by default. They select tabs. If they refresh, the last selected tab is opened by default. When the user turns edit mode on, **the url hash is removed**. The last selected tab remains selected. If the user selects another tab, the url hash isn't set, but the newly selected tab is displayed correctly. If the user saves their changes, the selected tab remains selected. However, if they refresh the page, the default tab replaces the previously selected tab. Not setting the url hash when editing a page layout simplifies the code. I'm okay with this tradeoff as the feature is primarily meant to let users share specific tabs of their records. **This behavior will also be used for record page layout once edit mode is supported.** https://github.com/user-attachments/assets/869657a1-6895-4ade-816c-972c77aaab9e Closes https://github.com/twentyhq/core-team-issues/issues/1784
The #1 Open-Source CRM
🌐 Website · 📚 Documentation · Roadmap ·
Discord ·
Figma
Installation
See: 🚀 Self-hosting 🖥️ Local Setup
Does the world need another CRM?
We built Twenty for three reasons:
CRMs are too expensive, and users are trapped. Companies use locked-in customer data to hike prices. It shouldn't be that way.
A fresh start is required to build a better experience. We can learn from past mistakes and craft a cohesive experience inspired by new UX patterns from tools like Notion, Airtable or Linear.
We believe in Open-source and community. Hundreds of developers are already building Twenty together. Once we have plugin capabilities, a whole ecosystem will grow around it.
What You Can Do With Twenty
Please feel free to flag any specific needs you have by creating an issue.
Below are a few features we have implemented to date:
- Personalize layouts with filters, sort, group by, kanban and table views
- Customize your objects and fields
- Create and manage permissions with custom roles
- Automate workflow with triggers and actions
- Emails, calendar events, files, and more
Personalize layouts with filters, sort, group by, kanban and table views
Customize your objects and fields
Create and manage permissions with custom roles
Automate workflow with triggers and actions
Emails, calendar events, files, and more
Stack
- TypeScript
- Nx
- NestJS, with BullMQ, PostgreSQL, Redis
- React, with Recoil, Emotion and Lingui
Thanks
Thanks to these amazing services that we use and recommend for UI testing (Chromatic), code review (Greptile), catching bugs (Sentry) and translating (Crowdin).
Join the Community
- Star the repo
- Subscribe to releases (watch -> custom -> releases)
- Follow us on Twitter or LinkedIn
- Join our Discord
- Improve translations on Crowdin
- Contributions are, of course, most welcome!




