How to Build Legal Products

The definitive tutorial for Community.lawyer's "no code" App Builder. Learn by building an app that (a) helps the public create a Power of Attorney; and (b) qualifies leads for your firm.

Last updated: Dec 16, 2019

By Thomas F. Officer, Design Lead

Part 1

From zero to live app

Welcome to the definitive Community.lawyer tutorial! The purpose of this tutorial is to learn how to use our "no code" App Builder. The App Builder is used to create web apps that collect data, automate documents, and nearly anything else a questionnaire-based expert system can do.

This tutorial works by guiding you through the process of building a real Legal App. We'll start with the simpliest possible app, then slowly add complexity. In the end, you will create an app that helps members of the public draft a power of attorney. We think this is the best type of app to start with for two reasons:

  1. This type of app provides a thorough tour of the App Builder (and an instructive technical challenge!); and
  2. This app also invites some interesting conversations about the implications of software in the legal service industry (are you interested in continuing this conversation? Keep in touch to hear from us and other legal professionals).

You're going to build an app that includes the following features:

  • An online form for collecting data
  • 2x automated document templates (Word & PDF)
  • Google Sheets integration
  • Branding & Payments

With these skills, you'll be able to build a wide range of Legal Apps. We're excited to see what you come up with.

Let's get started!

This is the first app we're going to build (the simpliest possible app). All this app does is ask the end-user for their name, then repeats that name back to them. The reason we're starting with such a simple app is it allows us to quickly experience the entire development procedure from build to launch.

The first thing we need to understanding when building our apps is Page Blocks. Continue to Chapter 1.1.

1.1 Page Blocks

Page Blocks are the "front-end" of your app, i.e. the web pages the end-user interacts with.

Let's start a new app (click "start new app" on your dashboard). Upon starting, you're brought into the App Builder.

The App Builder has six tabs, one of which is Blocks. This is where you will spend most of your time while building your app.

There are twelve different block types, all of which are available to you with the 'Add block' button. Blocks are divided into three groups:

  1. Page Blocks: The web pages your end-users will see.
  2. Logic Blocks: The "background code" of your app. This is how you create variables that represent legal concepts like "if the # of years between today and this person's birthday is less than 18, they are a minor."
  3. Repeating Blocks: Allows you to repeat a set of blocks over and over (known as a loop). These blocks are beyond the scope of this tutorial, but you can learn more about loops here.

Add Question Block

To build our first app (the simplest possible app), we need to collect the end-user's first name. In order to ask the end-user a question, we need a specific kind of Page Block: a Question Block.

Click "Add block" and add a Question Block to your app. Afterwards, your app should look like this:

When you run your app (which you can do at any time by clicking "run" in the upper right-hand corner), each Page Block is displayed to the end-user, one at a time, in the order you've organized them in the App Builder. Except, if you add "display if" logic to a block, it will only appear under certain conditions.

Clarification: It does not matter what order Logic Blocks appear in. The end-user will never see Logic Blocks; they are the "background code" of your app.

That's it regarding Page Blocks for now. Continue to Chapter 1.2 to learn about questions.

1.2 Questions & Variables

Questions can only be added to Question Blocks (you can add multiple questions on a single Question Block).

There are nineteen different types of Questions (e.g. yes/no, radio, number, etc). Deciding which question to use is a matter of first determining what kind of data you want to collect (i.e. if you want to collect a number to be used in calculations, use a number type question). We will go deeper into variables and data-types in Part 2.

Add Short Text Question

Let's ask for the end-user's name. Add a 'short text' question to your Question Block. Afterwards, your block should look like this:

Notice the yellow box to the right of your new question: this represents the variable your question just created. Every piece of data collected by your app is represented as a variable. This question created a new variable called variable_1. Rename the variable to first_name and add a label to the question, like this:

It's best practice to give your variables semantic names; meaning, names that, at-a-glance, let you know what kind of data the variable represents (such as "company_president_name").

Questions collect data from the end-user, and all data in your app is represented as a variable. Variables can be used in a number of ways. For example, in our app, we just defined a variable for the end-user's name: we can perform functions on that name such as "how many characters does this piece of text have?"

Interpolate client_name

We want to repeat the end-user's name back to them. We can do that by (1) adding a Final Block; and then (2) adding the first_name variable to the Final Block (adding a variable to a Block or document template is known as "interpolating"). Let's do this step by step.

Click "Add block" and select Final Block (this type of block does not have a "continue button"). On this block, type "Hello". As you type, you may notice that a toolbox has opened alongside (these toolboxes generally allow you to configure whatever it is you're working on). Use the "Add variable" button on this toolbox to add first_name to the Final Block:

Well done! Our super simplistic app is almost done. The last step is testing it and deploying it for live use.

1.3 Activating Your App

Your apps all begin in "Test Mode", meaning they are not live on the internet. While in Test Mode, your app:

  • Has free access to all features.
  • Can only be accessed by you, the app author.
  • Includes a "Test Mode" badge on all Page Blocks.
  • Includes watermarks on all document templates.
  • Any emails to 3rd parties are routed to your email address.

You can deploy your app to the internet (i.e. get it out of Test Mode) by "activating" it. Click on the Activation tab to begin that process:

Activation Types

There are two options for activating your app: (1) to your account; or (2) to a community. In either type of activation you can share your app with other people, the difference between them is how other people find your app.

  1. My Account — Nobody except you can find your app online. The only instance where other people can use your app is if you provide a special shareable link to them.
  2. Community — If you activate to a public community, your app is available for anyone on the internet to use; if you activate to a private Community, your app is only available to the members of that community. In either case, you control the permissions (for example, is usage free or for a price? can end-users only run the app or can they also copy it?). Note that when you activate an app to a public community, we host the app for free (unless it uses certain features that are only available under paid subscriptions).

We're going to activate our app to a public community.

Apps in a community must have an App Page: a standalone website that describes the app and the author (you), and provides end-users with a button(s) to start, duplicate, or purchase the app (depending on what permissions you provide).

App Page

Under the App Page subtab, fill in details about your app, including the minimum required fields (which are: Title, Short description, Long description, Jurisdiction tag, and Legal taxonomy tag).

After you complete your App Page, go back to the Activation Settings subtab and publish your app with the following activation configuration:

  1. Communities
  2. A public community, e.g. Community.lawyer
  3. Provide both 'run' and 'copy to account' permissions
  4. After you select 'copy to account', you can specify how others may copy your app. We're going to allow others to duplicate our app for free: select 'duplicate' and keep the price at $0.00.

Click "Save" to activate your app.

🎉 Well done! You just built and published your very own app.

It may seem like a small thing, but building and deploying software to the internet is a superpower. We need more people doing it, if only because that's the surest way to start seeing better legal products. We also think building and sharing software is a Good thing because doing it well means engaging with the world, iterating on feedback, and pushing boundaries.

In a moment, we're going to start building our Power of Attorney app. But first, we need to address something important: the shoulders we stand on.

When you build a Community.lawyer app, you're building a Docassemble Interview. Docassemble is an open-source expert system. We just created a layer on top of it (and added one or two features).

Tweet and get 1 month free

Help us spread the word about Docassemble and we'll give you a free Standard App Builder subscription for 1 month (allowing you to activate apps with all features). Here is how:

  1. Tweet a link to the App Page of any of your apps; and
  2. In your tweet, @ Docassemble and LawyerCommunity

We will respond and upgrade your account.

Continue this tutorial to learn how variables create logic in your app.

Part 2

Advanced Variables

Now that we've finished with our simplistic example, we're ready to start building our 'Power of Attorney' product. First, we're going to need to a lot more information than just the end-user's last name. While collecting this information, we're going to learn more about variables and how they can be used to create logic in our app.

2.1 Display If Logic

Let's imagine that our firm will only create Power of Attorneys for individuals who (a) have never created a Power of Attorney before; and (b) are 18+ years old.

Let's start with the issue of whether or not this is their first Power of Attorney. Add a Yes/No question that defines a variable called prior_poa_exists, like so:

If the end-user answers "yes" to this question (meaning, if prior_poa_exists is True) we can display a Final Block that kindly informs them we can't offer our services. If you're building off of the simplistic app we made in Chapter 1, we can edit the existing Final Block in our app. Otherwise, add a Final Block now.

On your Final Block, write a goodbye message to the end-user then click the 'Display if' toggle:

The 'Display if' toggle allows us to conditionally show this Final Block as the next block in sequence. By clicking the toggle, you get access to something called an Expression Editor, a tool for writing logic.

Expression Editor: Basic

Expression Editors appear in several places throughout the App Builder (specifically, they appear everywhere you see a 'Display if', 'Show if', or 'Conditionally insert' toggle). The purpose of the Editor changes depending on where it appears in the App Builder, but generally speaking it's purpose is to show/hide something. On a Page Block, you can use the 'Display if' toggle to conditionally display a block as the next page in sequence.

Edit your logical expression: After clicking the 'Display if' toggle, click "Edit expression" to open an Expresion Editor:

We want to conditionally display this Final Block based on whether or not the end user is interested in hiring our firm. We can do this with the following logical expression: prior_poa_exists is true, like so:

Well done! You just created your first logical expression.

Pro Tip: A valid logical expression for 'Display if', 'Show if', or 'Conditionally insert' must evaluate to True or False. For example, you can't conditionally display an element if "Thomas"; that doesn't make any sense. However, you can conditionally display an element if first_name equals "Thomas", because this condition is either True or False (i.e. it "evaluates" to True or False).

The end-result, which you can test by clicking "run" in the top-right corner of the App Builder, is that when the end-user answers "no" to the question "Are you interested in hiring my firm?" our Final Block is displayed.

Let's explore a more advanced Expression Editor use-case.

Expression Editor: Advanced

Let's imagine our firm will only work with clients who are 18+ years old. If we collect the end-user's date of birth, we can use an Expression Editor to calculate whether or not they are 18+.

Let's add a date question to our first block that defines a variable called client_dob, like so:

Now that we know the end-user's date of birth, there are two ways we could approach the problem of calculating whether or not they are 18+ years old:

  1. We could manually enter (or "hard code") the date on which you must be born before, e.g. "As of Dec 9, 2019, you must be born before Dec 9, 2001 to use this app"; or
  2. We could use an Expression Block to create a variable called is_18_plus that is True or False depending on whether or not the number of years between Today (meaning, the day on which the app is run) and the client's date of birth is 18.

Method #2 is superior. Can you see why? If we used method #1, you would have to edit your app every single day in order to keep it functional.

Now, what is an Expression Block?

To learn, continue to section 2.2. Logic Blocks.

2.2 Expression Block

The Expression Block is a type of Logic Block. The purpose of an Expression Block is to define a variable using a logical expression.

Logic Blocks

Logic Blocks create variables that are defined by the internal logic of the app (as opposed to questions that create variables that are defined by the end-user).

In this chapter, we're going to learn how to use the follow types of Logic Blocks:

  1. Expression Block: Used for creating variables that are the product of a logical expression.
  2. Text Block: Used for creating variables that are equal to a block of text.

Let's continue with the challenge we laid out at the end of chapter 2.1: now that we know the end-user's date of birth, how do we efficiently calculate whether or not they are 18+ years old?

We can use an Expression Block to create a variable called is_18_plus that is True or False depending on whether or not the number of years between Today (meaning, the day on which the app is run) and the client's date of birth is greater than or equal to 18.

Add an Expression Block:

Expression Blocks create varaibles. As always, when we create a variable, the first thing we want to do is change the variable's default name. Let's rename our Expression Block variable to is_18_plus:

Our ultimate goal is to create an expression that looks like this:

According to this expression, is_18_plus will be True if the number of years between Today and client_dob is greater than or equal to 18.

Pro Tip

Today is a default variable that is always available to you (meaning, you don't have to define it). Today equals the day on which the app is run.

What is 'years since'? This is an example of an operator. Operators allow you to create powerful expressions by comparing or manipulating two or more pieces of data. Here is another example:

Pro Tip

The operators you have access to in an Expression Editor depends on the type of data you're working with. For example, a date-type piece of data provides access to operators like 'years since' or 'formatted like Monday, December 9, 2019' while a text-type piece of data provides access to operators like 'character count' or 'join with a space to'. View a full list of operators and their corresponding datatypes in this User Manual article.

Now that we know whether or not the end-user is 18+ years old, we can edit our Final Block to be displayed under two conditions: (1) if the end-user indicates they have a prior Power of Attorney; or (2) if the end-user is not 18+ years old, like so:

Here is what our app looks like so far (we can get this bird's eye view by clicking "collapse all"):

Note: I've added names to the blocks (e.g. the Question Block is now called "Intro") to make it easier to visually scan the app.

2.3 Text Block

So far, we know our end-user's name and whether or not they want to hire our firm. Let's collect information about the exact type of services they want to hire us for.

Add another Question Block. Then, on that new Question Block, add a Checkbox question with the following options: (a) Will; (b) Power of Attorney; and (c) Healthcare directive. Like so:

Pro Tip

Multiple-choice questions, like checkboxes, define a variable and a specific set of values. The values each get a label. In the checkbox example above, the value "POA" has the label "Power of Attorney".

Eventually, we want this Intake App to draft an Engagement Letter. On that Letter, we'll want to describe the types of services the end-user is hiring us for. Another way of framing this challenge, we want to conditionally dislpay blocks of text about our services on our Engagement Letter (the condition being whether or not the end-user is hiring us for that particular service). Creating blocks of text for this purpose is a perfect use-case for Text Blocks.

Add a Text Block: Click "Add block" and select "Text Block".

Like other Logic Blocks, the Text Block creates a variable. Let's rename the variable on our Text Block to will_text:

Let's define will_text to equal a block of text that describes what our 'wills' service includes and its cost (we can also rename the Block itself to make it easier to visually scan our app):

Repeat 2x: Let's create two more Text Block variables for poa_text and health_directive_text:

In chapter 3, we're going to conditionally interpolate these variables on our Engagement Letter. For now, let's add one last Page Block to our app and learn how these new Text Block variables can save us time drafting duplicative content.

Add a Final Block: Let's add a second Final Block. This Final Block will not include any 'Display if' logic, which means it will act as the concluding block for those individuals that get past the first Final Block. On this Final Block, we can include a thank you message, like so:

After our thank you message, we want to list the services for which we've been hired. We have variables that encapsulate the descriptions/price of each service we offer; our goal now is to conditionally add those variables to this block. One way we can do that is with the Note Element.

Note Elements just allow you to add text on a Page Block. However, Notes have two features that make them more powerful than simply writing text directly on a Block: (1) You can add a Note Elements above / below questions; and (2) You can add 'Show If' logic to a Note.

We're going to add three Notes with 'Show If' logic to our Final Block. This will allow us to conditionally interpolate our Text Block variables. For each Note, this is a 3 step process:

  1. Add a note element: Click "Element" and select "Note".
  2. Add a variable to the Note; specifically, one of the Text Block variables that describes our services. I will start with the will_text variable:
  3. Add 'Show If' logic to the Note: Click "Show if" to access an Expression Editor, then select the appropriate variable + condition. In this instance, since my note includes the will_text variable, I am going to select services: "Will" is true:

Now repeat this process for the other two Text Block variables. In the end, your Final Block should look something like this:

2.3 Conclusion

Well done! 🎉 You now know enough to create online forms (Page Blocks) that incorporate conditional logic (Expressions).

Up next, we're going to add to our app:

  • An online form for collecting data
  • 2x automated document templates (Word & PDF)
  • Google Sheets integration
  • Branding & Payments

Duplicate App

Interested to see how we made this app? Visit this App Page to duplicate our version:

View App Page

Part 3

Automating documents

Learn how to take the information you're collecting and add it to dynamic document templates. In this chapter, we're going to automate the Power of Attorney word document. We'll also ask the end-user if they're interested in hiring our firm for doc review or adjacent legal services. If the end-user says yes, our app will automate an Intake Form pdf.

Power of Attorney Template

Before we jump into automating our Word template, we need to review the information required for a Power of Attorney.

Here is a Power of Attorney template we can use as the basis for our own. On this template, we can see that we need the following data:

  • Principal name
  • Principal date of birth
  • Agent name
  • Agent date of birth
  • Powers granted: (a) real estate; (b) personal property; and/or (c) digital property
  • Whether or not the agent's powers continue to be effective after Principal is incapacitated
  • Today's date
  • Principal's signature

For the remainder of this section, we will simply add questions (and Question Blocks) to our app so that we can collect the above information. If you feel comfortable collecting this information on your own, skip to Section 3.1 to start building the automated Word template.

Adding Questions

After we determine that our end-user qualifies for a Power of Attorney (i.e. they have not created a prior Power of Attorney and they are 18+ years old), let's present them with a Question Block(s) where we collect the information we need.

First, the Power of Attorney template requires the end-user's full name. We're currently only collecting their first name. No problem; we can simply change the label to our first question from "First name" to "Full name". We can also change the associated variable from first_name to full_name (notice that the interpolated instances of first_name automatically change to full_name).

Next, let's add a Question Block after our conditionally displayed Final Block:

On this new Question Block, we can collect information about the attorney-in-fact (the individual receiving powers). We need two pieces of data: name (variable aif_name) and date of birth (variable aif_dob):

Next, we can add a Question Block to collect information about the scope of powers granted, like so:

In the block above, we're defining two variables: powers_granted and incapacitated_power. The powers_granted variable is multiple choice where the options are: real property, personal property, and digital assets.

Finally, let's add a Signature Block to collect the end-user's signature:

That is all the information we need to assemble our Power of Attorney Word template. Continue to Chapter 3.1 to learn how!

3.1 Word Templates

There are two methods of adding Word templates to your app: (1) build a template inside the App Builder with the Community.lawyer Word Editor; or (2) build a template in Microsoft Word and then upload it to the App Builder.

The primary difference between these two methods is the act of adding variables to your template. In Microsoft Word, you must use special syntax to designate a variable (learn more about this syntax here). In the Community.lawyer Word Editor, adding variables is a simple button click. The only drawback to using our Editor is that we don't provide all the formatting options Microsoft does.

Our Power of Attorney Template does not require special text formatting, so we will create our template in the Community.lawyer Word Editor.

Dec. 17, 2019 update: we're coming out with a Microsoft Word plug-in very soon (ETA late Jan. 2020). This will make it much easier to add variables and conditional logic to uploaded Word documents.

Creating Word Templates

You create a Word template under the Templates tab. Click "Create" under the Word Template section:

You'll be prompted to name your Word template. After you do so, click "edit".

You can use the Word Template editor to draft documents as you would in Microsoft Word. Although you can't use all the formatting options of Microsoft Word, you can do things like change font type/size/color, change text alignment, and add ordered/unordered lists.

Let's copy & paste our Power of Attorney template into this Word editor:

Variables that you need to replace in the Power of Attorney template are wrapped in two curly brackets: {{ variable_name }}.

Interpolating variables

It's easy to interpolate variables on Word Templates. Just click "insert variable" and select the variable you wish to add from the dropdown:

Conditionally interpolating text

Truly automating documents means doing more than simply "find & replace". It means conditionally inserting or editing clauses based on the fact-pattern at hand. For example, our Power of Attorney template includes a series of clauses regarding the scope of power granted (see "FIRST" in the template). We can automate each clause with this simple two-step process:

Step 1: Create a new variable that is equal to the clause we wish to conditionally insert. Do that by clicking "Create variable". I'm starting with the 'real property clause', so I am naming this new variable real_property_text:

The definition of this variable should be the text we wish to see in our document for the 'real property clause' (you can reference the template Power of Attorney for suggested definitions to these clauses):

Step 2: Toggle 'conditionally insert' and use the Expression Editor to create a logical rule for when this clause should be interpolated. For this clause, the rule is powers_granted: "real property" is true:

Repeat this process for the two remaining clauses for personal property and digital assets.

Quick Clarification: Text Blocks

Eventually, you'll return the Blocks tab of the App Builder (not yet! We have more work to do on this template). When you do, you may notice some new blocks:

These new blocks are Text Blocks. Text Blocks are used to create variables that are defined as a piece of text. This is what you were doing when you clicked "create variable" from within the Word Editor.

Else Statements

Sometimes, we want to conditionally interpolate one of two possible pieces of text. There is exactly the situation in our Power of Attorney template regarding the words "shall" and "shall not".

On your template, replace "{{ shall or shall not }}" with a variable called incapacitated_text. Give this variable a definion of "shall" and conditionally insert it only if incapacitated_power is true:

Now we're going to define an "else statement", meaning a fallback defition for this variable to take if incapacitated_power is false. Our else statement will be "shall not" and we create that by simply writing it in this second text field in the variable editor sidebar:

Interpolating Dates

There are three dates we need to interpolate on our template: client dob, attorney-in-fact dob, and today.

First, note that although we never asked the end-user "what day is it today?" we nonetheless have a variable available to us called Today. This is a default variable you always have access to and it's value is equal to whatever day the app is run.

Second, interpolating date variables requires special formatting. Without that formatting, you may notice that the dates come out on documents looking like this: 2019-11-27T00:00:00-05:00. 🙁 Yikes! Although this looks ugly, it's actually a technically accurate value for a date to have. Such technical accuracy is what allows you to do calculations on dates.

It is very simple to format your dates in a way that is appropriate for documents. Simply follow the instructions in the User Manual article.

Attach Word Template to Page Block

Well done! When finished, your Power of Attorney template should look something like this:

The final step to automating this Word template is attaching it to a Page Block. You can attach this template to the same Final Block where we attached the PDF template.

3.2 PDF Templates

A Power of Attorney has significant effects. It's also an indicator of other possible legal issues (elder care? estate planning? etc). By helping someone create a Power of Attorney, we're in a special position: we have their attention (perhaps because this product is advertised as free on our website?) and we know what type of legal services they may be interested in.

Let's ask the end-user whether or not they want to hire our firm to review their Power of Attorney document.

Add a new Question Block immediately before the last Final Block. On this Block, we can define a variable (review_poa) that is True if the end-user wants to hire our firm:

If the end-user decides to hire our firm, we can assemble a PDF Intake Form.

Here is a template Intake Form you can use. Notice that we've already collected all the information we need to assemble this document.

Upload PDF

You can make any PDF fillable by uploading it to your app. You upload PDFs under the Template tab:

Upon uploading a PDF, you enter into the PDF Template Editor. This is where we can draw "targets" for where the app should fill in data.

Interpolate text

Interpolating variables on your PDF is a two-step process:

  1. Draw a target:
  2. Choose a value for the PDF target. You can either use this dropdown (see below) or double-click directly on the target:

Interpolate signature

To interpolate a signature, we must use a special type of target: the Signature target. Click "signature" to draw a signature target, then select the signature variable.

Interpolate checkboxes

Checkbox targets operate differently than Text or Signature targets. Checkbox targets can only function with boolean variables (i.e. variables whose value is either True of False). If the variable is true, a check mark is added to the checkbox target.

We have a boolean variable that is perfect for this checkbox:

Draw a checkbox target for 'Review Power of Attorney'. Then, assign review_poa is true:

Attach PDF to Final Block

Remember, document templates must be attached to a Page Block in order to be assembled. Let's attach our Intake Form PDF to the same Final Block as our Power of Attorney Word doc. However, let's conditionally attach the PDF only if review_poa is true (meaning, only if the end-user opts to hire our firm to review their PoA):

3.3 Conclusion

Nice! 😎 You're halfway through.

  • An online form for collecting data
  • 2x automated document templates (Word & PDF)
  • Google Sheets integration
  • Branding & Payments

Duplicate App

Interested to see how we made this app? You can duplicate our version of the Power of Attorney app. Just click "duplicate" on the App Page linked here:

View App Page

Part 4

Pushing Data

You've made it quite far! In this chapter, we're going to learn how to push data from our app to an outside database.

Paid feature: You can test the pushing data feature for free. However, if you want to activate an app with this feature, you must purchase a Standard or Premium subscription. Or use the promotion advertised at the end of Chapter 1.3 to get a free Standard subscription for 1 month.

4.1 Pulling from a Table

Tables are useful when there is one piece of information which, if you collected it from the end-user, would allow you to infer many other pieces of information. For example, imagine that our law firm is national; meaning, we have an office in every state in the United States. If we can identify which state the end-user lives in, we can refer to our table to determine the address of our nearest law office.

Add Table

There are two methods of adding tables in your app: (1) Upload a CSV ("comma separated values", i.e. a spreadsheet); or (2) create a table from scratch. Tables operate the same way regardless of whether you upload it or created it from scratch.

Here is a pre-made table for your Intake App: download table. This table is a Google Sheet, to download as a CSV click File > Download > Comma Separated Values:

After your download this table, upload it to your app under the Data Source tab. Click "Add data source" then select "CSV Upload":

Now that you've created a Data Source (in this instance, a table), notice that the data source is represented as a variable:

Like all variables, we want to take a moment and change the default name. The best practice for naming Data Source variables is to choose a name that is the plural form of whatever data the Data Source includes. The Data Source that we just added to our app includes information about all 50 states (for each state, the table includes information regarding (a) the state's abbreviated name; and (b) the address of our law office in that state); therefore, one possible name for this Data Source is list_of_states.

Add a Data Source Selector

Now that we have a Data Source that includes information about all 50 states, we want to ask the end-user which state they live in (this is the one piece of information we need that will allow us, using our table, to infer which of our 50 law offices we should refer them to).

Our Data Source has 3 columns: (1) State; (2) Abbreviation; and (3) Nearest office. We want the end-user to select a row from column (1). We can do exactly that with a Data Source Selector question.

Like any other type of question, the Data Source Selector must be added to a Question Block. Now, we currently have two Question Blocks on our app. Although there is no limit to the number of questions you can ask per block, asking too many questions on a single block makes for a poor user experience. Let's take a moment to add another Question Block to our app. Let's add this block after our Introduction and before the block where we ask about our services:

Remember, our Data Source Selector question allows the end-user to select a row from the first column of our table. That first column is a list of states. Accordingly, let's frame our Data Source Selector question in the context of asking about their home address generally. Meaning, before we add the Data Source Selector question, let's add two Short Text questions for the end-user's street and city/town (as always, taking care to rename our variables):

Now we can add our Data Source Selector question. Click "question" and select "Data Source Selector".

We can add a label of "State." As for naming the Data Source question's variable, the best practice is to choose a name that is the singular form of whatever data the Data Source includes. Accordingly, we can name this variable state:

The last step to configuring your Data Source Selector question is selecting which one of your data sources you want this question to pertain to. Currently, our app only has 1 data source: the list_of_states table we created in this chapter. Let's select that:

Let's test run our app to see if this Data Source Selector question behaves as we expect:

🎉 Very good! The Data Source Selector is allowing the end-user to select a row from the first column of our table (in this instance, the first column of our table includes a list of all 50 states). This is why we call the first column of a table the "key column." The key column populates the Data Source Selector question which allows the end-user to select a row from the table.

Pro Tip: The key column of your table (or Google Sheet) should only include unique values.

Let's quickly finish this Question Block by adding a Short Text question to collect the end-user's zip code (we can define the variable as address_zip):

Interpolate Table Data

You can interpolate table data (i.e. add it to a document) only after you attach that table to a Data Source Selector question. Now that we have done that, we can interpolate the end-user's state on our PDF Intake Form.

Clarification: Why can only interpolate a table's data after you attach the table to a Data Source Selector question? Because, if you don't add a Data Source Selector question, your app has no mechanism by which it can distinguish one row in your table from another.

On our PDF, we can now fill in the text fields for the end-user's address. And for the 'State' text field, we can interpolate a cell from within our table. Which cell? Well, the end-user is selecting a row with the Data Source Selector question, so we just need to designate a column. In this instance, we can use the column labeled 'Abbreviation':

Notice this variable's name: state: Abbreviation. This is a combination of our Data Source Selector variable (state) and the name of a column in our table (Abbreviation). Remember, the end-user is selecting a row with the Data Source Selector question. When we select a column (as we just did on our PDF), we're providing the app with coordinates with which to find a single cell in our table (row + column = cell). That's cool! 😎

Pro Tip: Table + Data Source Selector is the fastest way to create a lengthy dropdown. Here is a User Manual article on using this recipe to quickly create a dropdown of all 50 states.

4.1 Google Sheets

We're going to push the data from our app to a Google Drive spreadsheet (known as Google Sheets). We can pretend this Sheet is our law firm's database. The principles for pushing data from your app to Google Sheets are the same as those for pushing to Clio or Zapier.

Add Integration

Before you can continue with this chapter, you must integrate your Google Drive account with your Community.lawyer account. This is done under your dashboard, on the Settings tab, under Integrations. If you need help, just follow the instructions in this User Manual article.

Structure Your Sheet

Before we can send information to an outside database, we need to think about the structure of our data. For us, in practical terms, that means we need to add columns to our Google Sheet. We need a column header for each piece of data we want to push.

Our app is quite simple (but innovative!) so we don't need a complex Sheet. Two column wills suffice; one for client name and another for client date of birth:

Replicate this Google Sheet in your own Google Drive account. This is where you're going to push data to.

Add Sheets Integration to a Block

You, as the app author, have precise control over how your app operates. This includes determining exactly when, and what, data is sent to Google Sheets. You need to make the following decision: which Block do you want to send data from? This is significant because you can only send data that has been collected in prior blocks. That's why it's typical to see Google Sheet integrations on the Final Block(s) of apps.

Add a Google Sheet integration to the Final Block of your app. You do that by going to the Final Block, clicking "integration" and selecting Google Sheets:

Now, we need to decide whether we're going to add a new row to our Sheet or update an existing one. Let's assume that we don't have any data about this client in our Sheet. Meaning, let's create a new row:

You'll now be prompted to select which Google Sheet you want to push data to.

Great! You're on your way to sending data to Google Sheets and building not just a doc automation tool but an integrated, data collection tool. The only step left is delineating exactly what data you want to push.

Select Data to Push

Each piece of data you send to Google Sheets is known as a "parameter." We have two pieces of data to push, so we're going to add two parameters. Click "Add paramter" to get started:

For each paramter, we need to designate a column in Google Sheets (known as "Sheets field") and a piece of data from our app ("value"). After you add your two parameters, your Sheets integration should look like this:

That's it! Give your app a test run to make sure it's all working as expected.

4.3 Pull Data

Pulling data into your app means you do not have to ask the end-users for information you already have; instead, you can pull that information into your app from wherever it is stored.

There are two methods of pulling data into your app:

  1. Pulling data from a table
  2. Pulling data from a 3rd party database, e.g. Clio or Google Sheets
Paid feature: You can test the pulling data feature for free. However, if you want to activate an app with this feature, you must purchase a Standard or Premium subscription.

Pulling data from a table

Adding a table to your app is a powerful tool. It allows you to create relationships between pieces of information, which in turn allows you to ask the end-user for a one piece of information and then infer the value of many other pieces of information.

Pulling data from a 3rd party database

You can connect your app to two different 3rd party databases: Clio and Google Sheets. This allows you to pull data into your app from these databases.

Google Sheets

Clio

The principles of pulling data from Google Sheets (above video) and Clio are the same (learn more about pulling data from Clio). In both instances you need to (1) Add a data source; then (2) add a Data Source Selector question. However, Clio has one unique ability: running Community.lawyer apps from inside your Clio dashboard. This is know as a "custom action" — Learn more about Custom Actions in this User Manual Article.

4.2 Conclusion

Crushing it! 🤘 You're done with the technical challenge of building an app. Up next, the true challenge.

  • An online form for collecting data
  • 2x automated document templates (Word & PDF)
  • Google Sheets integration
  • Branding & Payments

Duplicate App

Interested to see how we made this app? You can duplicate our version of the Power of Attorney app. Just click "duplicate" on the App Page linked here:

View App Page

Part 5

Final Touches

By reaching this Chapter, you have successfully completed all the technical challenges of building an app, including:

  • Manipulating data with logical expressions;
  • Creating powerful document templates; and
  • Integrating with an outside database.

These are important skills and they will open many doors for you. However, learning these skills just marks the beginning. And, to be frank, these skills are not the most difficult part of building successful Legal Products.

The most difficult part of building Legal Products is (a) figuring out what to build; and then (b) after you build it (which will be a breeze for you!), figuring out how to market it (meaning, how will people find your app? How will you sustain your app's ongoing development?).

In this final chapter, you'll learn about two sets of features that can help you with the challenge of marketing your app. Specifically, you will learn how to brand your app and how, on a technical level, you can generate revenue.

5.1 Branding

In the end, your users don't need to know about Community.lawyer. Who are we to them? It's you they care about and it's your brand they trust.

In this chapter, we'll learn how to "whitelabel" apps. The end result will be that the end-user only sees your brand, not Community.lawyer's.

Logo and Styles

The ability to customize the look of your app, including the ability to add a logo, can be found under the Settings tab:

Custom Domains / Subdomains

You can host your apps on personalized URLs (instead of the generic app.community.lawyer URL). There are two ways you can personalize your app's URL:

  1. Custom domains: For those of you with subscriptions to the Premium tier, you can now host your apps from completely custom domains or subdomains that you own. For example, your law firm may have its main website at www.demolaw.xyz. You may want to provide links from that site to public-facing apps that run on a subdomain like automate.demolaw.xyz. With custom domains, this is now possible. Learn more in this User Manual article.
  2. Personalized subdomains: Even if you don't have a Premium subscription, you now have a personalized subdomain. The subdomain is a combination of your username and the community.lawyer domain. For example, my subdomain is thomas.community.lawyer and all my apps are now hosted from that base URL.

If you want to add a custom domina / subdomain, follow the instructions in this User Manual article.

5.2 Payments

There are three ways to generate revenue with your app:

  1. In-app payments
  2. Selling your app
  3. Selling subscriptions to a bundle of your apps

In-App Payments

You can use a Payment Block to collect credit car payments directly in your app:

Here are some examples for how we could use the Payment Block in our Power of Attorney app:

  • Charge for simple document assembly: Currently, in our Power of Attorney app, we're offering the underlying document for free. We could add a Payment Block before our Final Block to require the end-user to submit a payment before continuing (note: It's not good practice to suprise someone with a payment; this should be advertised well in advance).
  • Upselling complex document assembly: Most documents (e.g. a will, contracts, letters, etc) have a simple version and a complex version. Our app could help end-users assemble the simple version for free while collecting information about whether or not the complex version is more appropriate/valuable. If it is, we can offer the complex version for a cost (this is known as upselling).
  • Cross-selling legal services: We could offer services that are adjacent to the one for which our app is advertised. For example, we're currently helping folks create a Power of Attorney, what can we infer about their current situation? Do they need to plan for succession? Do they have medical issues? We have this individual's attention and, hopefully, trust; this is a perfect position from which to kindly notifying them about our other services (this is known as cross-selling).

Sell Your App

You can sell your app as a whole. In practical terms, this means allow others to duplicate your app for a price. The ability to duplicate your app is a permission you set when you activate your app:

Sell Subscriptions to an App Store

You can bundle your apps together into a single dashboard (known as a "community"). You can sell access to this community either as a flat-fee or a subscription. You can create your own community directly from your Account:

After you click "Start a community", you can decide how people sign up (ivite only or is there a public sign up page?) and whether or not a fee is due on sign up (flat or subscription?):

Payment Processors

You can integrate your app with the following payments processors:

  • Stripe (all payment types); and
  • LawPay (only for payments collected directly in your app).

5.3 Conclusion

You did it!

  • An online form for collecting data
  • 2x automated document templates (Word & PDF)
  • Google Sheets integration
  • Branding & Payments

So, where do we go from here?

I'm ready to build

Go for it! Your Community.lawyer account includes the ability to build and test apps for free (only pay when you want to launch).

Start building

I want to hire an app developer

Get a free quote from app developers who leverage Community.lawyer to build apps faster at lower cost.

Get a quote

I want to see examples

Discover apps made by other legal service professionals. Certain apps can be duplicated for free.

Discover apps