Building PostedIn: the workflow behind a LinkedIn content service
Inside PostedIn’s Next.js product: bilingual public pages, a private client workspace, content review and publishing decisions that matter beyond the interface.

The visible part of PostedIn is straightforward: a person requests LinkedIn content, reviews a prepared batch and publishes it. Building the product means deciding what happens between those steps.
Has the request been accepted? Is the brief complete? Does the customer have access to the right workspace? Has a post actually been published, or did the network stop answering? Those questions shape the software more than the number of cards on a dashboard.
I founded and built PostedIn as a content service with a working client portal. This article describes its current implementation and the decisions a founder or agency should consider when commissioning a similar product.
Public pages and private work have different jobs
The public website needs to explain the offer, load reliably and make its content available to search engines. The customer workspace needs sessions, permissions, editable records and integrations.
PostedIn uses a separate Next.js marketing application with Arabic and English routes. Those public pages are exported as static files and served by Nginx. A server-backed Next.js application handles the dashboard and API on the same VPS, with authentication protecting the customer workspace.
That division has an operational benefit: publishing an article or correcting a plan description does not require restarting the application that handles customer work. The two sides still need consistent links, branding and product data. A separate build is not an excuse for two conflicting versions of the offer.
Next.js documents static exports as an option for generating HTML, CSS and JavaScript at build time. It fits these public pages. The authenticated workflows still need a server.
Keep the plan rules in one place
A pricing card makes promises that the application has to enforce. If the card says 15 text posts, the application needs to distinguish that allowance from a plan that includes images or carousels.
PostedIn’s marketing pricing imports the same plan catalogue used by the application. It holds the numeric allowances, preparation windows and feature gates. Localized explanations sit around those shared values.
This reduces a familiar source of mistakes: changing the price on the website while leaving an old limit in the client workspace. It does not remove the need to review the wording. “Four carousels within 30 posts” and “30 posts plus four carousels” are different offers even when both mention the number four.
For a founder, this is a useful scoping question: which rules must stay consistent across marketing, checkout, account access and the operator’s controls?
A receipt, approval and delivery are different records
PostedIn currently supports a local payment-review workflow. A customer submits a request and receipt; an operator checks it before approving payment. Content preparation then follows the accepted brief and applicable plan.
Treating those events as one “done” checkbox would leave both the customer and operator guessing. The public request needs a status. Payment needs a decision. Content needs a preparation and review process. Sending an email does not, by itself, prove that the promised batch exists or reached the customer’s inbox.
The same distinction applies to a free request. It still needs acceptance, a complete brief, account setup and preparation. Free changes the commercial terms; it does not remove the work of delivering the service.
Before designing a similar portal, write a sentence for every transition: who can do it, what must already be true, and what the customer sees afterward. Those sentences are a better starting point than a list of dashboard widgets.
Review belongs before automatic publishing
New PostedIn accounts start with manual publishing. Customers can inspect and edit their content before enabling the automatic queue, and LinkedIn authorization must be configured first.
The scheduler works with the customer’s configured publishing time and plan cadence. It records publication state so the system can distinguish waiting work from an attempted or completed publication. A queue needs those distinctions because an external API is outside the application’s control.
Consider a timeout after a publish request. Retrying immediately might create a duplicate if the first request succeeded but its response was lost. PostedIn’s handling of uncertain publication outcomes calls for review instead of blindly treating every timeout as a safe retry.
The broader lesson applies to email, payments and third-party integrations: define what “confirmed” means, retain the evidence, and make an uncertain outcome visible to the operator. A green success message should represent an observed result.
Customer data needs boundaries inside the app
PostedIn stores application records in SQLite and keeps customer-uploaded media behind authenticated routes. Workspaces are separated by tenant, so checking that a visitor is signed in is only the first step. The requested record also has to belong to a workspace that person may access.
This belongs in server-side checks, not only in a filtered interface. A hidden button cannot enforce access. Plan restrictions need the same treatment: the server must decide whether an action is permitted, even when the interface already explains the limit.
Testing these workflows uses disposable databases and simulated publishing. A test should not send a real LinkedIn post, reuse a customer’s receipt or change a live subscription just to prove that a button works.
Arabic support reaches beyond translated headings
PostedIn has distinct Arabic and English URLs, localized metadata and right-to-left layouts where appropriate. Currency, signup requirements and payment explanations also reflect the service’s current Egyptian market.
A translated heading is only one part of the work. Forms, navigation, dates, validation messages and confirmation states need to remain understandable in both languages. The plan rules should stay the same while the explanations read naturally.
For an agency delivering a bilingual product, include these states in the brief and review process. Otherwise the main landing page may look complete while the first error message sends a customer back into the wrong language.
What I would ask before building your version
- ●Who uses the product, and what should each role be allowed to see or change?
- ●Which steps are automatic, and which require a person to make a decision?
- ●What proves that a payment, delivery or external publication succeeded?
- ●What happens when an integration stops responding halfway through a request?
- ●Which parts can be published independently, and how do we return to a working release?
Those answers determine the scope of the first release. PostedIn is one example of the resulting software: a public offer connected to the less visible work of delivering it.
If you are planning a service portal or a SaaS product, send me the workflow you need to support. You can also read how PostedIn works for customers or try the content-calendar example before exploring the rest of the product.