The semicolon is required, because without an indication of where that context ends (through a semicolon, newline, etc), if cannot know where the condition ends, and the conditional block begins. Compare:
$ if echo then foo then; then :; fi
then foo then
$ if echo then; then :; fi
then
-d is a test to check if the next argument is a directory. From help test (because test is equivalent to [):
-d FILE True if file is a directory.
For example:
$ mkdir foo
$ if [ -d foo ]; then
> echo foo is a dir
> fi
foo is a dir
$1 is the first argument passed to your program. For example:
$ cat > script << 'EOF'
> #!/bin/sh
> echo "$1"
> EOF
$ chmod +x script
$ ./script foo
foo
As an aside, you should quote $1 here, because otherwise it can expand into multiple arguments, resulting in a syntax error from [:
$ dir="foo bar"
$ [ -d $dir ]
sh: 2: [: foo: unexpected operator
$ [ -d "$dir" ]
$