diff --git a/domain_meta.info b/domain_meta.info
index 17d74d6..8802686 100644
--- a/domain_meta.info
+++ b/domain_meta.info
@@ -1,6 +1,8 @@
 name = Domain Meta Tags
 description = Provides <a href="http://drupal.org/project/metatag">Metatag</a> integration with <a href="http://drupal.org/project/domain">Domain Access</a> module.
 package = SEO
+core = 7.x
 dependencies[] = domain
 dependencies[] = metatag
-core = 7.x
\ No newline at end of file
+files[] = domain_meta.tokens.inc
+files[] = domain_meta.metatag.inc
diff --git a/domain_meta.install b/domain_meta.install
index 666a53e..9ec969a 100644
--- a/domain_meta.install
+++ b/domain_meta.install
@@ -20,4 +20,54 @@ function domain_meta_disable() {
  */
 function domain_meta_enable() {
   db_query("UPDATE {system} SET weight = 10 WHERE name = 'domain_meta'");
-}
\ No newline at end of file
+}
+
+/**
+ * Implements hook_schema()
+ */
+function domain_meta_schema() {
+  $schema = array();
+
+  $schema['domain_meta'] = array(
+    'fields' => array(
+      'vid' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'description' => t('VID of node revision.'),
+      ),
+      'domain_meta_canonical_domain' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'descriiption' => t('The domain ID of the conanicial domain metatag.'),
+      ),
+    ),
+    'primary key' => array('vid'),
+  );
+
+  return $schema;
+}
+
+/**
+ * Add domain_meta table
+ */
+function domain_meta_update_7101() {
+  $table = array(
+    'fields' => array(
+      'vid' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'description' => t('VID of node revision.'),
+      ),
+      'domain_meta_canonical_domain' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'descriiption' => t('The domain ID of the conanicial domain metatag.'),
+      ),
+    ),
+    'primary key' => array('vid'),
+  );
+
+  db_create_table('domain_meta', $table);
+
+  return $ret;
+}
diff --git a/domain_meta.module b/domain_meta.module
index 31f8441..b0d08ea 100644
--- a/domain_meta.module
+++ b/domain_meta.module
@@ -4,6 +4,14 @@
  * Core module functions for the Domain Meta Tags module.
  */
 
+/**
+ * Implements hook_ctools_plugin_api().
+ */
+function domain_meta_ctools_plugin_api($owner, $api) {
+  if ($owner == 'metatag' && $api == 'metatag') {
+    return array('version' => 1);
+  }
+}
 
 /**
  * Implements hook_metatag_config_default().
@@ -20,6 +28,7 @@ function domain_meta_metatag_config_default() {
       'title' => array('value' => variable_get('site_slogan') ? '[site:name] | [site:slogan]' : '[site:name]'),
       'canonical' => array('value' => '[site:url]'),
     );
+    $configs[$config->instance] = $config;
   }
   return $configs;
 }
@@ -36,6 +45,13 @@ function domain_meta_metatag_config_instance_info() {
   return $info;
 }
 
+function domain_meta_metatag_bundled_config_alter(array &$configs) {
+  // Add an override for canonical to the nodes
+  if (array_key_exists('node', $configs)) {
+    $configs['node']->config['canonical']['value'] = '[node:canonical-url]';
+  }
+}
+
 /**
  * Implements hook_page_build().
  */
@@ -47,6 +63,136 @@ function domain_meta_page_build(&$page) {
   }
 }
 
+function domain_meta_form_alter(&$form, $form_state, $form_id) {
+  if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] . '_node_form' == $form_id) {
+    $node = $form['#node'];
+    $domain_opts = array(
+      '-10' => t('Automatic'),
+      '-5' => t('Use active domain'),
+    );
+    $domains = domain_domains();
+    foreach ($domains as $domain) {
+      if ($domain['domain_id'] === 0) {
+        $domain_opts[-1] = check_plain($domain['sitename']);
+      }
+      else {
+        $domain_opts[$domain['domain_id']] = check_plain($domain['sitename']);
+      }
+    }
+
+    if (!(property_exists($node, 'domain_meta_canonical_domain')) ||
+        ($node->domain_meta_canonical_domain === NULL) ||
+        ($node->domain_meta_canonical_domain === FALSE)) {
+      $default = -10;
+    }
+    elseif ($node->domain_meta_canonical_domain == 0) {
+      $default = -1;
+    }
+    else {
+      $default = $node->domain_meta_canonical_domain;
+    }
+
+    $form['domain']['domain_meta_canonical_domain'] = array(
+      '#type' => 'select',
+      '#title' => t('Canonical meta-tag URL'),
+      '#description' => t('The domain to use in the metatag as the canoncial URL.  This will not redirect users, but will tell search engines the one domain here that is the official copy.  This reduces the "dupicate data" penalty.'),
+      '#options' => $domain_opts,
+      '#default_value' => $default,
+    );
+  }
+}
+
+function domain_meta_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
+  switch ($op) {
+    case 'load':
+      domain_meta_node_load($node);
+      break;
+    case 'insert':
+    case 'update':
+      domain_meta_node_save($node);
+      break;
+    default:
+      break;
+  }
+}
+
+/**
+ * Given a node (which may not be the current requested page), return
+ * the canonical URL for the node.  If the canonical domain "Automatic" (-10),
+ * then the first domain the node is published to is the canonical domains.
+ * If the node is set to "Send to all affiliates", then the default domain
+ * is used.
+ *
+ * @param $node
+ *
+ * @return string The canonical URL for the node.
+ */
+function domain_meta_canonical_url_for_node($node) {
+  $canonical_domain = $node->domain_meta_canonical_domain;
+
+  // Go with "automatic"?
+  if (($canonical_domain === NULL) ||
+      ($canonical_domain == '-10')) {
+    $domain_id = ($node->domain_site) ? domain_default_id() : reset($node->domains);
+    $domain = domain_lookup($domain_id);
+  }
+  elseif ($canonical_domain == '-5') {
+    $domain = domain_get_domain();
+  }
+  else {
+    $domain = domain_lookup($canonical_domain);
+  }
+
+  // Assemble!
+  $path = drupal_get_path_alias('node/' . $node->nid);
+  $canonical_url = domain_check_scheme($domain['scheme']) . '://' . $domain['subdomain'] . $path;
+
+  return domain_get_uri($domain);
+}
+
+/**
+ * Implements hook_node_load()
+ */
+function domain_meta_node_load($nodes, $types) {
+  $vids = array();
+
+  // Collect all the VIDs and set a reasonable default
+  foreach ($nodes as $n) {
+    $vids[] = $n->vid;
+    $nodes_by_vid[$n->vid] = $n;
+    $n->domain_meta_canonical_domain = -10;
+  }
+
+  if (empty($vids)) {
+    return;
+  }
+
+  // Load them all in one call -- at least TRY to optimize the DB calls.
+  $results = db_select('domain_meta', 'dm')
+    ->fields('dm', array('vid', 'domain_meta_canonical_domain'))
+    ->condition('vid', $vids, 'IN')
+    ->execute();
+
+  foreach($results as $record) {
+    $nodes_by_vid[$record->vid]->domain_meta_canonical_domain = $record->domain_meta_canonical_domain;
+  }
+}
+
+function domain_meta_node_insert($node) {
+  domain_meta_node_save($node);
+}
+
+function domain_meta_node_update($node) {
+  domain_meta_node_save($node);
+}
+
+function domain_meta_node_save($node) {
+  if ($node->domain_meta_canonical_domain === -1) {
+    $node->domain_meta_canonical_domain = 0;
+  }
+  drupal_write_record('domain_meta', $node);
+}
+
 /**
  * Gets active domains from domain.module.
  *
@@ -63,4 +209,4 @@ function _domains_metatag_get_active_domains() {
     }
   }
   return $active_domains;
-}
\ No newline at end of file
+}
diff --git a/domain_meta.tokens.inc b/domain_meta.tokens.inc
new file mode 100644
index 0000000..47ccbaa
--- /dev/null
+++ b/domain_meta.tokens.inc
@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * Implements hook_token_info.
+ */
+function domain_meta_token_info() {
+  $info = array();
+
+  $info['tokens']['node']['canonical-url'] = array(
+    'name' => t('Canonical URL'),
+    'description' => t('A domain-sensitive canonical for a node.'),
+  );
+
+  return $info;
+}
+
+/**
+ * Implements hook_tokens.
+ */
+function domain_meta_tokens($type, $tokens, array $data = array(), array $options = array()) {
+  $replacements = array();
+
+  if ($type == 'node') {
+    foreach($tokens as $name => $original) {
+      switch ($name) {
+        case 'canonical-url':
+          $replacements[$original] = domain_meta_canonical_url_for_node($data['node']);
+      }
+    }
+  }
+
+  return $replacements;
+}
