diff --git a/help/.gitignore b/help/.gitignore
index f40fbd8ba564..2d2f5954fc09 100644
--- a/help/.gitignore
+++ b/help/.gitignore
@@ -3,3 +3,4 @@ _site
.jekyll-cache
.jekyll-metadata
vendor
+_src/helpContentMap.tsx
diff --git a/help/_plugins/SitePostRender.rb b/help/_plugins/SitePostRender.rb
index b51f25cce68b..b0cdd7968b41 100644
--- a/help/_plugins/SitePostRender.rb
+++ b/help/_plugins/SitePostRender.rb
@@ -21,50 +21,323 @@ def self.process_page(page)
# Parse the page's content for header elements
doc = Nokogiri::HTML(page.output)
- # Create an array to store the prefix for each level of header (h2, h3, h4, etc.)
- prefix = {}
-
- # Process all
, , and elements in order
- doc.css('h2, h3, h4, h5').each do |header|
- # Check if the header starts with a short title in square brackets
- header_text = header.text.strip
- if header_text.match(/^\[(.*?)\]/)
- # Extract the short title from the square brackets
- short_title = header_text.match(/^\[(.*?)\]/)[1]
-
- # Set the `data-toc-title` attribute on the header
- header['data-toc-title'] = short_title
-
- # Remove the short title from the visible header text
- header_text = header_text.sub(/^\[.*?\]\s*/, '')
- header.content = header_text
+ # Check if the page is a reference page
+ if page.path.start_with?("ref/")
+ @help_mapping ||= {}
+ @help_mapping[page.path.chomp('index.md')] = doc.at('.product-content')
+ else
+ # Create an array to store the prefix for each level of header (h2, h3, h4, etc.)
+ prefix = {}
+
+ # Process all , , and elements in order
+ doc.css('h2, h3, h4, h5').each do |header|
+ # Check if the header starts with a short title in square brackets
+ header_text = header.text.strip
+ if header_text.match(/^\[(.*?)\]/)
+ # Extract the short title from the square brackets
+ short_title = header_text.match(/^\[(.*?)\]/)[1]
+
+ # Set the `data-toc-title` attribute on the header
+ header['data-toc-title'] = short_title
+
+ # Remove the short title from the visible header text
+ header_text = header_text.sub(/^\[.*?\]\s*/, '')
+ header.content = header_text
+ end
+
+ # Determine the level of the header (h2, h3, h4, or h5)
+ level = header.name[1].to_i # 'h2' -> 2, 'h3' -> 3, etc.
+
+ # Generate the ID for the current header based on its (cleaned) text
+ clean_text = header_text.downcase.strip
+ header_id = CGI.escape(clean_text.gsub(/\s+/, '-').gsub(/[^\w\-]/, ''))
+
+ # Store the current header's ID in the prefix array
+ prefix[level] = header_id
+
+ # Construct the full hierarchical ID by concatenating IDs for all levels up to the current level
+ full_id = (2..level).map { |l| prefix[l] }.join('--')
+
+ # Assign the generated ID to the header element
+ header['id'] = full_id
+
+ puts " Found h#{level}: '#{header_text}' -> ID: '#{full_id}'"
+ end
+
+ # Log the final output being written
+ puts " Writing updated HTML for page: #{page.path}"
+
+ # Write the updated HTML back to the page
+ page.output = doc.to_html
+ end
+ end
+
+
+ # Generate helpContent.tsx once all pages have been processed
+ Jekyll::Hooks.register :site, :post_render do |site|
+ generate_help_content(site)
+ end
+
+ def self.generate_help_content(site)
+ puts " Generating helpContent.tsx from rendered HTML pages..."
+
+ output_dir = File.join(site.source, "_src")
+ FileUtils.mkdir_p(output_dir) unless Dir.exist?(output_dir)
+
+ output_file = File.join(output_dir, "helpContentMap.tsx")
+
+ help_content_tree = generate_help_content_tree()
+
+ help_content_string = to_ts_object(help_content_tree)
+
+ components = analyze_used_components(help_content_string)
+
+ # Generate the import block
+ import_block = generate_imports(components)
+
+ ts_output = generate_ts_output(import_block, help_content_string)
+
+ File.write(output_file, ts_output)
+
+ puts "✅ Successfully generated helpContent.tsx"
+ end
+
+ def self.analyze_used_components(content)
+ components = {
+ 'View' => content.include?(' content.include?(' content.include?(' content.include?(' ReactNode;
+
+ type HelpContent = {
+ /** The content to display for this route */
+ content: ContentComponent;
+
+ /** Any children routes that this route has */
+ children?: Record;
+
+ /** Whether this route is an exact match or displays parent content */
+ isExact?: boolean;
+ };
+
+ const helpContentMap: HelpContent = #{help_content_string}
+
+ export default helpContentMap;
+ export type {ContentComponent};
+ TS
+ end
+
+ def self.generate_help_content_tree()
+ tree = {}
+
+ @help_mapping.each do |route, node|
+ parts = route.sub(/^ref\//, '').sub(/\.md$/, '').split('/')
+ current = tree
+
+ parts.each_with_index do |part, i|
+ is_dynamic = part.start_with?(':') || part.match?(/^\[.*\]$/)
+ part_key = is_dynamic ? part : part.to_sym
+
+ current[:children] ||= {}
+ current[:children][part_key] ||= {}
+
+ if i == parts.length - 1
+ jsx_content = html_node_to_RN(node, 1).rstrip
+
+ current[:children][part_key][:content] = <<~TS.chomp
+ ({styles}: {styles: ThemeStyles}) => (
+ #{jsx_content}
+ )
+ TS
+ end
+
+ current = current[:children][part_key]
end
+ end
+
+ tree[:content] = <<~JSX
+ () => null
+ JSX
+ tree
+ end
+
+ def self.html_node_to_RN(node, indent_level = 0)
+ node_processors = {
+ 'div' => method(:process_div),
+ 'p' => method(:process_paragraph),
+ 'ul' => method(:process_unordered_list),
+ 'li' => method(:process_list_item),
+ 'h1' => method(:process_heading),
+ 'h2' => method(:process_heading),
+ 'h3' => method(:process_heading),
+ 'h4' => method(:process_heading),
+ 'h5' => method(:process_heading),
+ 'h6' => method(:process_heading),
+ 'strong' => method(:process_bold),
+ 'b' => method(:process_bold),
+ 'em' => method(:process_italic),
+ 'i' => method(:process_italic),
+ 'a' => method(:process_link),
+ 'text' => method(:process_text),
+ }
- # Determine the level of the header (h2, h3, h4, or h5)
- level = header.name[1].to_i # 'h2' -> 2, 'h3' -> 3, etc.
+ # Use the processor if available, otherwise use default processing
+ processor = node_processors[node.name]
+ if processor
+ processor.call(node, indent_level)
+ else
+ process_default(node, indent_level)
+ end
+ end
- # Generate the ID for the current header based on its (cleaned) text
- clean_text = header_text.downcase.strip
- header_id = CGI.escape(clean_text.gsub(/\s+/, '-').gsub(/[^\w\-]/, ''))
+ def self.process_div(node, indent_level)
+ children = node.children.map do |child|
+ next if child.text? && child.text.strip.empty?
+ html_node_to_RN(child, indent_level + 1)
+ end.compact.join("\n")
+
+ "#{' ' * indent_level}\n#{children}\n#{' ' * indent_level}"
+ end
- # Store the current header's ID in the prefix array
- prefix[level] = header_id
+ def self.process_heading(node, indent_level)
+ return "#{' ' * indent_level}#{node.text.strip}"
+ end
- # Construct the full hierarchical ID by concatenating IDs for all levels up to the current level
- full_id = (2..level).map { |l| prefix[l] }.join('--')
+ def self.process_unordered_list(node, indent_level)
+ items = node.xpath('./li').map do |li|
+ contains_ul = li.xpath('.//ul').any?
- # Assign the generated ID to the header element
- header['id'] = full_id
+ li_parts = li.children.map { |child| html_node_to_RN(child, 0) }
+
+ if contains_ul
- puts " Found h#{level}: '#{header_text}' -> ID: '#{full_id}'"
+ indented_li_parts = li_parts.map do |part|
+ part.lines.map { |line| "#{' ' * (indent_level + 3)}#{line.rstrip}" }.join("\n")
+ end.join("\n")
+
+ "#{' ' * (indent_level + 2)}<>\n#{indented_li_parts}\n#{' ' * (indent_level + 2)}>"
+ else
+ "#{' ' * (indent_level + 2)}#{li_parts.join}"
+ end
end
- # Log the final output being written
- puts " Writing updated HTML for page: #{page.path}"
+ <<~TS.chomp
+ #{' ' * indent_level}
+ TS
+ end
+
+ def self.process_list_item(node, indent_level)
+ '' # handled in
+ end
+
+ def self.process_paragraph(node, indent_level)
+ inner = node.children.map { |c| html_node_to_RN(c, indent_level + 1) }.join
+
+ style_classes = ['styles.textNormal']
+ style_classes << 'styles.mt4' if node.previous_element&.name == 'ul'
+ style_classes << 'styles.mb4' if node.next_element&.name == 'p'
+
+ "#{' ' * indent_level}#{inner.strip}"
+ end
+
+ def self.process_bold(node, indent_level)
+ "#{node.text}"
+ end
+
+ def self.process_italic(node, indent_level)
+ "#{node.text}"
+ end
+
+ def self.process_link(node, indent_level)
+ href = node['href']
+ link_text = node.children.map { |child| html_node_to_RN(child, 0) }.join
+ "#{link_text.strip}"
+ end
+
+ def self.process_text(node, indent_level)
+ node.text
+ end
+
+ def self.process_default(node, indent_level)
+ node.children.map { |child| html_node_to_RN(child, indent_level) }.join
+ end
+
+ def self.to_ts_object(obj, indent = 0)
+ spacing = ' ' * indent
+ lines = ["{"]
- # Write the updated HTML back to the page
- page.output = doc.to_html
+ return "null" if obj.nil?
+ return obj.to_s if obj.is_a?(Numeric)
+ return obj.to_s if obj.is_a?(TrueClass) || obj.is_a?(FalseClass)
+ return obj.inspect if obj.is_a?(String)
+
+ if obj.is_a?(Array)
+ items = obj.map { |item| to_ts_object(item, indent + 1) }
+ return "[]" if items.empty?
+
+ return "[\n" +
+ items.map { |item| "#{spacing} #{item}" }.join(",\n") +
+ "\n#{spacing}]"
+ end
+
+ obj.each do |key, value|
+ key_str = key.is_a?(Symbol) ? key.to_s : key.inspect
+ key_line_prefix = ' ' * (indent + 1) + "#{key_str}: "
+
+ if value.is_a?(Hash) || value.is_a?(Array)
+ nested = to_ts_object(value, indent + 1)
+ lines << key_line_prefix + nested + ","
+ elsif value.is_a?(String) && value.include?("\n")
+ value_lines = value.split("\n")
+ first_line = value_lines.shift
+ rest_lines = value_lines.map { |l| ' ' * (indent + 1) + l }
+ lines << ([key_line_prefix + first_line] + rest_lines).join("\n") + ","
+ else
+ lines << key_line_prefix + value.inspect + ","
+ end
+ end
+
+ lines << ' ' * indent + "}"
+ lines.join("\n")
end
+
end
end
diff --git a/help/ref/home/index.md b/help/ref/home/index.md
new file mode 100644
index 000000000000..9aad7c4e66a2
--- /dev/null
+++ b/help/ref/home/index.md
@@ -0,0 +1,58 @@
+---
+layout: product
+title: Expensify Chat
+---
+
+# Chat
+
+Chat is the foundation of New Expensify. Every expense, expense report, workspace, or member has an associated "chat", which you can use to record additional details, or collaborate with others. Every chat has the following components:
+
+## Header
+
+This shows who you are chatting with (or what you are chatting about). You can press the header for more details on the chat, or additional actions to take upon it.
+
+## Comments
+
+The core of the chat are its comments, which come in many forms:
+
+- **Text** - Rich text messages stored securely and delivered via web, app, email, or SMS.
+- **Images & Documents** - Insert photos, screenshots, movies, PDFs, or more, using copy/paste, drag/drop, or the attach button.
+- **Expenses** - Share an expense in the chat, either to simply track and document it, or to submit for reimbursement.
+- **Tasks** - Record a task, and optionally assign it to someone (or yourself!).
+
+## Actions
+
+Hover (or long press) on a comment to see additional options, including:
+
+- **React** - Throw a ♥️😂🔥 like on anything!
+- **Reply in thread** - Go deeper by creating a new chat on any comment.
+- **Mark unread** - Flag it for reading later, at your convenience.
+
+## Composer
+
+Use the composer at the bottom to write new messages:
+
+- **Markdown** - Format text using **bold**, *italics*, and [more](https://help.expensify.com/articles/new-expensify/chat/Send-and-format-chat-messages).
+- **Mention** - Invite or tag anyone in the world to any chat by putting an @ in front of their email address or phone number (e.g., **@awong@marslink.web**, or **@415-867-5309**).
+
+---
+
+# Inbox
+
+The Inbox is a prioritized "to do" list, highlighting exactly what you need to do next. It consists of:
+
+## Priorities
+
+At the top of the Inbox are the most important tasks you should do first, which include:
+
+- Expense reports waiting on you
+- Tasks assigned to you
+- Chats that have mentioned you
+- Anything you have pinned
+
+## Chats
+
+Beneath the priorities are a list of chats (with unread chats highlighted in bold), in one of two view modes:
+
+- **Most Recent** - Lists every chat, ordered by whichever was most recently active.
+- **Focus** - Only lists chats with unread messages, sorted alphabetically.
diff --git a/help/ref/r/:concierge/index.md b/help/ref/r/:concierge/index.md
new file mode 100644
index 000000000000..9c5c9d40f3fa
--- /dev/null
+++ b/help/ref/r/:concierge/index.md
@@ -0,0 +1,9 @@
+---
+layout: product
+title: Expensify Chat
+---
+
+# Concierge
+
+Concierge is available 24/7 to answer any question you have about anything — whether that's how to get set up, how to fix a problem, or general best practices.
+Concierge is a bot, but it's really smart and can escalate you to a human whenever you want. Say hi — it's friendly!
diff --git a/help/ref/r/:expense/:expensifyCard/index.md b/help/ref/r/:expense/:expensifyCard/index.md
new file mode 100644
index 000000000000..48c1cc5fae60
--- /dev/null
+++ b/help/ref/r/:expense/:expensifyCard/index.md
@@ -0,0 +1,10 @@
+---
+layout: product
+title: Expensify Chat
+---
+
+# Expensify Card
+
+An "Expensify Card" expense corresponds to a "posted" (meaning, finalized by the bank) purchase.
+
+Expensify Card expenses cannot be reimbursed as they are centrally paid by the bank account linked to the workspace.
diff --git a/help/ref/r/:expense/:manual/index.md b/help/ref/r/:expense/:manual/index.md
new file mode 100644
index 000000000000..5e9c619a57ed
--- /dev/null
+++ b/help/ref/r/:expense/:manual/index.md
@@ -0,0 +1,9 @@
+---
+layout: product
+title: Expensify Chat
+---
+
+
+# Manual
+
+A "manual" expense has had all its details specified by the workspace member. It was not imported from any system, or scanned from a receipt.
diff --git a/help/ref/r/:expense/:pendingExpensifyCard/index.md b/help/ref/r/:expense/:pendingExpensifyCard/index.md
new file mode 100644
index 000000000000..9c5566ed8fa2
--- /dev/null
+++ b/help/ref/r/:expense/:pendingExpensifyCard/index.md
@@ -0,0 +1,12 @@
+---
+layout: product
+title: Expensify Chat
+---
+
+# Expensify Card (pending)
+
+A "pending" Expensify Card expense represents a purchase that was recently made on the card, but has not yet "posted" – meaning, it has not been formally recognized as a final, complete transaction.
+
+Any changes made to this expense will be preserved when the expense posts, typically 2-7 days later.
+
+Pending transactions cannot be approved, as the final expense amount will not be confirmed until it posts.
diff --git a/help/ref/r/:expense/:scan/index.md b/help/ref/r/:expense/:scan/index.md
new file mode 100644
index 000000000000..1f5a15ca84fb
--- /dev/null
+++ b/help/ref/r/:expense/:scan/index.md
@@ -0,0 +1,8 @@
+---
+layout: product
+title: Expensify Chat
+---
+
+# Scanned
+
+A "scanned" expense was created by extracting the relevant details using the Concierge AI.
diff --git a/help/ref/r/:expense/index.md b/help/ref/r/:expense/index.md
new file mode 100644
index 000000000000..b3ac81bba5e4
--- /dev/null
+++ b/help/ref/r/:expense/index.md
@@ -0,0 +1,16 @@
+---
+layout: product
+title: Expensify Chat
+---
+
+# Expense
+
+Every expense gets a dedicated chat to discuss that specific expense. The expense consists of:
+
+- **Receipt** – Attach a photo or document to this expense.
+- **Amount** – The financial total of this transaction.
+- **Description** – A general explanation of what this expense was for.
+- **Merchant** – The business this purchase was made at.
+- **Date** – The day on which the purchase was made.
+
+The expense chat is shared with everyone in the approval flow, and will maintain an audit trail of all historical changes.
diff --git a/help/ref/r/:expenseReport/index.md b/help/ref/r/:expenseReport/index.md
new file mode 100644
index 000000000000..77907b5ff549
--- /dev/null
+++ b/help/ref/r/:expenseReport/index.md
@@ -0,0 +1,13 @@
+---
+layout: product
+title: Expensify Chat
+---
+
+# Expense Report
+
+Every expense report gets a dedicated chat to discuss expenses, approvals, or anything you like. The expense report chat:
+
+- Is shared with everyone in the approval flow configured inside the workspace.
+- Will maintain an audit trail of all historical workflow actions (i.e., approvals).
+
+Press the attach button to add more expenses, or press the header for more options. Press on any expense to go deeper.
diff --git a/help/ref/r/:policyAdmins/index.md b/help/ref/r/:policyAdmins/index.md
new file mode 100644
index 000000000000..4932f67775c1
--- /dev/null
+++ b/help/ref/r/:policyAdmins/index.md
@@ -0,0 +1,14 @@
+---
+layout: product
+title: Expensify Chat
+---
+
+# #admins
+
+Every workspace automatically receives a special `#admins` chat room. Every admin is automatically added to this room as a member. The `#admins` room is used for several purposes:
+
+- **Talking with Concierge, your setup specialist, or your account manager** – When you first create the workspace, Concierge and a setup specialist will be added. Feel free to ask any setup questions you have about how to configure the workspace, onboard your team, connect your accounting, or anything else you might need.
+
+- **Monitoring workspace changes** – Every `#admins` room shows an audit trail of any configuration changes or significant events happening inside the workspace.
+
+- **Chatting with other admins** – The `#admins` room is a useful space for workspace admins to chat with each other about anything, whether or not it relates to Expensify.
diff --git a/help/ref/r/:policyExpenseChat/index.md b/help/ref/r/:policyExpenseChat/index.md
new file mode 100644
index 000000000000..fc4a92ed89ff
--- /dev/null
+++ b/help/ref/r/:policyExpenseChat/index.md
@@ -0,0 +1,13 @@
+---
+layout: product
+title: Expensify Chat
+---
+
+# Workspace
+
+Every workspace member gets a special chat between them and all workspace admins. This is a good place for workspace members to ask questions about expense policy, for workspace admins to explain changes, or for any "formal" conversation to occur between members and admins. Press the attach button to:
+
+- **Create expense** – This will submit an expense to the workspace for reimbursement.
+- **Split expense** – This will split an expense between the member and the workspace (e.g., for a business meal that brings a spouse).
+
+All past expense reports are processed here and stored for historical reference.
diff --git a/help/ref/r/index.md b/help/ref/r/index.md
new file mode 100644
index 000000000000..12f5890f472c
--- /dev/null
+++ b/help/ref/r/index.md
@@ -0,0 +1,59 @@
+---
+layout: product
+title: Expensify Chat
+---
+
+
+# Chat
+
+Chat is the foundation of New Expensify. Every expense, expense report, workspace, or member has an associated "chat", which you can use to record additional details, or collaborate with others. Every chat has the following components:
+
+## Header
+
+This shows who you are chatting with (or what you are chatting about). You can press the header for more details on the chat, or additional actions to take upon it.
+
+## Comments
+
+The core of the chat are its comments, which come in many forms:
+
+- **Text** – Rich text messages stored securely and delivered via web, app, email, or SMS.
+- **Images & Documents** – Insert photos, screenshots, movies, PDFs, or more, using copy/paste, drag/drop, or the attach button.
+- **Expenses** – Share an expense in the chat, either to simply track and document it, or to submit for reimbursement.
+- **Tasks** – Record a task, and optionally assign it to someone (or yourself!).
+
+## Actions
+
+Hover (or long press) on a comment to see additional options, including:
+
+- **React** – Throw a ♥️😂🔥 like on anything!
+- **Reply in thread** – Go deeper by creating a new chat on any comment.
+- **Mark unread** – Flag it for reading later, at your convenience.
+
+## Composer
+
+Use the composer at the bottom to write new messages:
+
+- **Markdown** – Format text using **bold**, *italics*, and [more](https://help.expensify.com/articles/new-expensify/chat/Send-and-format-chat-messages).
+- **Mention** – Invite or tag anyone in the world to any chat by putting an `@` in front of their email address or phone number (e.g., **@awong@marslink.web**, or **@415-867-5309**).
+
+---
+
+# Inbox
+
+The Inbox is a prioritized "to do" list, highlighting exactly what you need to do next. It consists of:
+
+## Priorities
+
+At the top of the Inbox are the most important tasks you should do first, which include:
+
+- Expense reports waiting on you
+- Tasks assigned to you
+- Chats that have mentioned you
+- Anything you have pinned
+
+## Chats
+
+Beneath the priorities are a list of chats (with unread chats highlighted in bold), in one of two view modes:
+
+- **Most Recent** – Lists every chat, ordered by whichever was most recently active.
+- **Focus** – Only lists chats with unread messages, sorted alphabetically.
diff --git a/help/ref/search/index.md b/help/ref/search/index.md
new file mode 100644
index 000000000000..88d3e1c0c7fb
--- /dev/null
+++ b/help/ref/search/index.md
@@ -0,0 +1,53 @@
+---
+layout: product
+title: Expensify Chat
+---
+
+
+# Reports
+
+Virtually all data can be analyzed and reported upon in the Reports page. The major elements of this page include:
+
+## Data type
+
+Start first by choosing the type of data you want to analyze, which can be:
+
+- **Expense** - Individual standalone expenses.
+- **Expense reports** - Groups of expenses processed in a batch.
+- **Chats** - Comments written by you and others.
+- **Invoices** - Expenses submitted to clients for payment.
+- **Trips** - Travel expenses booked with Expensify Travel or scanned with SmartScan.
+
+## Search
+
+A quick method of narrowing the results by keyword or more.
+
+## State filter
+
+Simple methods to filter the results by "state", including:
+
+- **All**
+- **Expenses/Expense/Invoices reports:**
+ - Draft - Only you can see that hasn't been shared yet.
+ - Outstanding - Submitted to someone and awaiting action.
+ - Approved - Approved, but awaiting payment.
+ - Done - Fully processed, no further action needed.
+ - Paid - Fully paid, no further action needed.
+
+- **Chats:**
+ - Unread - Not seen yet by you.
+ - Sent - Sent by you.
+ - Attachments - Image, movie, or document.
+ - Links - Hyperlinks.
+ - Pinned - Highlighted by you as important.
+
+- **Trips:**
+ - Current - Happening or in the future.
+ - Past - Already happened.
+
+## Results
+
+The core of the Reports page are the search results themselves.
+
+- Select a row to see additional options.
+- Tap on a row to see more detail.
diff --git a/help/ref/settings/index.md b/help/ref/settings/index.md
new file mode 100644
index 000000000000..a5d82e807173
--- /dev/null
+++ b/help/ref/settings/index.md
@@ -0,0 +1,18 @@
+---
+layout: product
+title: Expensify Chat
+---
+
+# Settings
+
+Here is where you configure Expensify exactly to your specifications:
+
+- **Profile** - Configure how you appear to others.
+- **Wallet** - See and manage your credit cards and bank accounts.
+- **Preferences** - Adjust how the app works for you.
+- **Security** - Lock down how you and others access your account.
+- **Workspaces** - Organize expenses for yourself and share with others.
+- **Subscriptions** - Manage payment details and history.
+- **Domains** - Advanced security and corporate card configuration.
+- **Switch to Expensify Classic** - Battle tested and reliable.
+- **Save the World** - Let Expensify.org help your favorite teacher!
diff --git a/help/ref/settings/workspaces/:policyID/index.md b/help/ref/settings/workspaces/:policyID/index.md
new file mode 100644
index 000000000000..469f92423df0
--- /dev/null
+++ b/help/ref/settings/workspaces/:policyID/index.md
@@ -0,0 +1,33 @@
+---
+layout: product
+title: Expensify Chat
+---
+
+# Workspace
+
+This is where you configure all the settings of the many features associated with your workspace.
+
+## Default features
+
+Here are the features that are enabled by default:
+
+- **Overview** - Configure how it appears to others.
+- **Members** - Add/remove members and admins.
+- **Workflows** - Configure submission, approval, and reimbursement.
+- **Categories** - Group expenses into a chart of accounts.
+- **Expensify Card** - Issue native Expensify Cards to employees.
+- **Accounting** - Sync with external accounting systems.
+
+## Optional features
+
+These can be enabled via More Features:
+
+- **Distance rates** - Configure mileage reimbursement.
+- **Company card** - Connect and manage third-party corporate card feeds.
+- **Per diem** - Configure daily rates.
+- **Rules** - Customize expense violations and set policy.
+- **Invoices** - Collect revenue from customers.
+- **Tags** - Group expenses by project or client.
+- **Taxes** - Track VAT and other taxes.
+- **Report fields** - Capture extra expense report information.
+
diff --git a/help/ref/settings/workspaces/:policyId/index.md b/help/ref/settings/workspaces/:policyId/index.md
new file mode 100644
index 000000000000..469f92423df0
--- /dev/null
+++ b/help/ref/settings/workspaces/:policyId/index.md
@@ -0,0 +1,33 @@
+---
+layout: product
+title: Expensify Chat
+---
+
+# Workspace
+
+This is where you configure all the settings of the many features associated with your workspace.
+
+## Default features
+
+Here are the features that are enabled by default:
+
+- **Overview** - Configure how it appears to others.
+- **Members** - Add/remove members and admins.
+- **Workflows** - Configure submission, approval, and reimbursement.
+- **Categories** - Group expenses into a chart of accounts.
+- **Expensify Card** - Issue native Expensify Cards to employees.
+- **Accounting** - Sync with external accounting systems.
+
+## Optional features
+
+These can be enabled via More Features:
+
+- **Distance rates** - Configure mileage reimbursement.
+- **Company card** - Connect and manage third-party corporate card feeds.
+- **Per diem** - Configure daily rates.
+- **Rules** - Customize expense violations and set policy.
+- **Invoices** - Collect revenue from customers.
+- **Tags** - Group expenses by project or client.
+- **Taxes** - Track VAT and other taxes.
+- **Report fields** - Capture extra expense report information.
+
diff --git a/help/ref/settings/workspaces/index.md b/help/ref/settings/workspaces/index.md
new file mode 100644
index 000000000000..5d9b1971839b
--- /dev/null
+++ b/help/ref/settings/workspaces/index.md
@@ -0,0 +1,24 @@
+---
+layout: product
+title: Expensify Chat
+---
+
+# Workspaces
+
+Workspaces allow for a wide range of features, including:
+
+- **Categorize** and **submit** expenses
+- **Approve** and **reimburse** expenses
+- Sync with **accounting packages**
+- Connect to **company card feeds**
+- Manage **Expensify Cards**
+- **Chat** with colleagues, partners, and clients
+- … and lots more!
+
+Workspaces come in two variations:
+
+- **Collect** workspaces start at $5/member, and include all the basics for running a small business.
+- **Control** workspaces start at $9/member, and provide advanced capabilities, more powerful accounting sync, and more sophisticated approval flows.
+
+In general you would create one Workspace for each company you manage. You can create and join as many workspaces as you like.
+